package com.cin.cma.server.biz.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.TypeReference;
import com.cin.cma.common.constant.BookingTransaction;
import com.cin.cma.common.constant.JynettyApiUriConstant;
import com.cin.cma.common.enums.OrderStatusEnum;
import com.cin.cma.common.enums.SystemErrorCode;
import com.cin.cma.common.exception.UserFriendlyException;
import com.cin.cma.common.model.ApiErrorInfo;
import com.cin.cma.common.model.ApiResponse;
import com.cin.cma.common.model.finixx.base.BaseRequest;
import com.cin.cma.common.model.finixx.base.BaseResponse;
import com.cin.cma.common.model.finixx.request.*;
import com.cin.cma.common.model.finixx.response.*;
import com.cin.cma.server.biz.model.core.client.FinixxSettingsDTO;
import com.cin.cma.server.biz.model.core.request.*;
import com.cin.cma.server.biz.model.core.response.*;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.cin.cma.common.enums.OpenApiErrorCode.*;

/**
 * @Author：wubo
 * @Date：2025/3/3 下午6:11
 */
@RestController
@Slf4j
@RequestMapping("core")
public class CoreController {
    @Value("${core-server.host}")
    String baseUri;

    //todo 改为读库？
    public FinixxSettingsDTO getFinixxSettings() {
        FinixxSettingsDTO result = new FinixxSettingsDTO();
        result.setChannelCd("WEIXIN");
        result.setPassWord("6E370235A6240B0150D3449967DDF2CA");
        result.setUserName("WEB");
        result.setAppKey("81F5BFBFE0AD49E8B7E1");
        result.setSerialNumber(IdUtil.fastSimpleUUID());
        result.setVersion("1.0.0.1");
        //todo 票类
        result.setPriceType("@会员票");
        result.setWorkSation("CMA");
        return result;
    }

    public String request(BaseRequest baseRequest, String url) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        //这段是通用的-start
        baseRequest.setSerialNumber(finixxSettings.getSerialNumber());
        baseRequest.setUserName(finixxSettings.getUserName());
        baseRequest.setAppKey(finixxSettings.getAppKey());
        baseRequest.setPassWord(finixxSettings.getPassWord());
        log.info("发起请求：{}：{}", url, JSON.toJSONString(baseRequest));
        //这段是通用的-end
        String body = HttpUtil.createPost(baseUri + url)
                .body(JSON.toJSONString(baseRequest))
                .execute()
                .body();
        log.info("返回结果：{}：{}", url, body);
        return body;
    }

    /**
     * 影院信息
     * {"success":true,"error":null,"data":{"code":"0420","version":"1.0.0.1","serialNumber":"8f5fe9551acc412dbcc0e5b5622534a9","result":0,"message":null,"id":"8566","locationCode":"53080201","name":"云南普洱墨江电影院","localFlag":true,"centerFlag":false,"taxPer":3.3000,"specialFundsPer":5.00,"went":0.50,"showFlag":false,"locationAbbreviation":"8566","address1":"云南普洱墨江电影院","address2":"","address3":"","address4":"","address5":"","phone":"15008816679","fax":"08794231357","firstOpenDate":"2023-10-16T16:00:00.000+00:00","crossBkgsFlg":"Y","ivrsLocationCd":null,"stateCountyCd":null,"noOfScreens":3,"noOfIdsScrns":0,"uploadCode":null,"contactPeople":"金海","corporation":"","seatQuantity":249,"property":"加盟","operatingStatus":2,"class":"县级"}}
     *
     * @param cinemaId
     * @return
     */
    public ApiResponse<LocalCinemaResponse> basicGetLocalCinema(String cinemaId) {
        BaseRequest baseRequest = new BaseRequest();
        baseRequest.setLocationCd(cinemaId);
        String requestBody = request(baseRequest, JynettyApiUriConstant.BASIC_GET_LOCAL_CINEMA);
        ApiResponse<LocalCinemaResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<LocalCinemaResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 获取渠道设置
     * {"success":true,"error":null,"data":{"code":"0419","version":"1.0.0.1","serialNumber":"8ac982c8be8c408ab7a47bf11057f025","result":0,"message":null,"ibtList":[{"cd":"BO","desc":"前台售票","saleDelayTime":300,"saleBeforeShowTime":45,"saleBookingDays":30,"saleMaxTickets":9999,"bookingFee":0,"bookingFlg":"X","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"BO","thirdParty":false},{"cd":"WEB","desc":"网上订购","saleDelayTime":10,"saleBeforeShowTime":45,"saleBookingDays":30,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"X","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"WEBBOOKING","thirdParty":false},{"cd":"IVRS","desc":"语音订购","saleDelayTime":10,"saleBeforeShowTime":45,"saleBookingDays":3,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"X","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"IVRS","thirdParty":false},{"cd":"WAP","desc":"手机APP","saleDelayTime":10,"saleBeforeShowTime":45,"saleBookingDays":30,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"X","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"WAP","thirdParty":false},{"cd":"WEIXIN","desc":"微信订购","saleDelayTime":10,"saleBeforeShowTime":45,"saleBookingDays":30,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"X","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"WEIXIN","thirdParty":false},{"cd":"KIOSK","desc":"自动售票机","saleDelayTime":10,"saleBeforeShowTime":45,"saleBookingDays":3,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"X","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"KIOSK","thirdParty":false},{"cd":"IDS","desc":"屏幕显示","saleDelayTime":10,"saleBeforeShowTime":45,"saleBookingDays":3,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"X","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"IDS","thirdParty":false},{"cd":"WEIBO","desc":"微博显示","saleDelayTime":0,"saleBeforeShowTime":45,"saleBookingDays":3,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"T","terminalPass":"","terminalCount":0,"authorizationNo":"0","modulus":"0","exponent":"0","authorizationFlg":false,"rcreUserCd":"WEIBO","thirdParty":true},{"cd":"CLOUD","desc":"电影云","saleDelayTime":10,"saleBeforeShowTime":20,"saleBookingDays":1,"saleMaxTickets":1,"bookingFee":0,"bookingFlg":"X","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"CLOUD","thirdParty":false},{"cd":"MTW","desc":"猫眼","saleDelayTime":0,"saleBeforeShowTime":45,"saleBookingDays":30,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"T","terminalPass":"","terminalCount":5,"authorizationNo":"0","modulus":"0","exponent":"0","authorizationFlg":false,"rcreUserCd":"MTW","thirdParty":true},{"cd":"GPW","desc":"微影","saleDelayTime":0,"saleBeforeShowTime":45,"saleBookingDays":30,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"T","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"GPW","thirdParty":true},{"cd":"NMW","desc":"百度糯米","saleDelayTime":0,"saleBeforeShowTime":45,"saleBookingDays":30,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"T","terminalPass":"","terminalCount":5,"authorizationNo":"","modulus":"","exponent":"","authorizationFlg":false,"rcreUserCd":"NMW","thirdParty":true},{"cd":"TAOBAO","desc":"淘票票","saleDelayTime":0,"saleBeforeShowTime":45,"saleBookingDays":30,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"T","terminalPass":"","terminalCount":5,"authorizationNo":"0","modulus":"0","exponent":"0","authorizationFlg":false,"rcreUserCd":"TAOBAO","thirdParty":true},{"cd":"LYT","desc":"龙影通","saleDelayTime":-10,"saleBeforeShowTime":45,"saleBookingDays":3,"saleMaxTickets":6,"bookingFee":0,"bookingFlg":"T","terminalPass":"","terminalCount":5,"authorizationNo":"0","modulus":"0","exponent":"0","authorizationFlg":false,"rcreUserCd":"LYT","thirdParty":true}]}}
     *
     * @param cinemaId
     * @return
     */
    public ApiResponse<IncreaseBookingSettingResponse> basicGetIbt(String cinemaId) {
        BaseRequest baseRequest = new BaseRequest();
        baseRequest.setLocationCd(cinemaId);
        String requestBody = request(baseRequest, JynettyApiUriConstant.BASIC_GET_IBT);
        ApiResponse<IncreaseBookingSettingResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<IncreaseBookingSettingResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 排期列表
     * {"success":true,"error":null,"data":{"code":"1004","version":"1.0.0.1","serialNumber":"69af375178de4dcebdf643de0f306231","result":0,"message":null,"sessions":[{"refSeqNo":"8566250226F82HVT0X","seqNo":"1","locationCd":"8566","showDate":"2025-02-26","filmCd":"001c0007202501","cinemaCd":"0000000000000002","cinemaName":"2号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1100,"saleOpen":false,"allocate":"true","dimensional":"3D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":32,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":35.0,"bookingFeeFlg":false,"filmDuration":144,"filmCode":"001c00072025","filmLongTitle":"哪吒之魔童闹海（数字3D）","filmShortTitle":"哪吒之魔童闹海（数字3D）","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"8566250226204DL8","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"8566250226468620PN","seqNo":"1","locationCd":"8566","showDate":"2025-02-26","filmCd":"001l0012202501","cinemaCd":"0000000000000001","cinemaName":"1号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1110,"saleOpen":false,"allocate":"true","dimensional":"2D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":23,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":30.0,"bookingFeeFlg":false,"filmDuration":88,"filmCode":"001l00122025","filmLongTitle":"您的声音","filmShortTitle":"您的声音","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"8566250226BP24FF","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"8566250226JXR4J4ZN","seqNo":"2","locationCd":"8566","showDate":"2025-02-26","filmCd":"001l0012202501","cinemaCd":"0000000000000001","cinemaName":"1号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1250,"saleOpen":false,"allocate":"true","dimensional":"2D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":23,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":30.0,"bookingFeeFlg":false,"filmDuration":88,"filmCode":"001l00122025","filmLongTitle":"您的声音","filmShortTitle":"您的声音","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"8566250226822RZB","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"85662502268VHT8H82","seqNo":"2","locationCd":"8566","showDate":"2025-02-26","filmCd":"001c0007202501","cinemaCd":"0000000000000002","cinemaName":"2号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1340,"saleOpen":false,"allocate":"true","dimensional":"3D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":30,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":35.0,"bookingFeeFlg":false,"filmDuration":144,"filmCode":"001c00072025","filmLongTitle":"哪吒之魔童闹海（数字3D）","filmShortTitle":"哪吒之魔童闹海（数字3D）","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"85662502262JTJF6","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"85662502262J48FND6","seqNo":"3","locationCd":"8566","showDate":"2025-02-26","filmCd":"00110680202401","cinemaCd":"0000000000000001","cinemaName":"1号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1430,"saleOpen":false,"allocate":"true","dimensional":"2D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":23,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":35.0,"bookingFeeFlg":false,"filmDuration":137,"filmCode":"001106802024","filmLongTitle":"唐探1900","filmShortTitle":"唐探1900","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"8566250226F6H8FZ","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"85662502264J2PVP6L","seqNo":"1","locationCd":"8566","showDate":"2025-02-26","filmCd":"001c0007202501","cinemaCd":"0000000000000003","cinemaName":"3号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1500,"saleOpen":false,"allocate":"true","dimensional":"3D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":50,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":35.0,"bookingFeeFlg":false,"filmDuration":144,"filmCode":"001c00072025","filmLongTitle":"哪吒之魔童闹海（数字3D）","filmShortTitle":"哪吒之魔童闹海（数字3D）","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"8566250226ZBL266","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"85662502260FX4FD6H","seqNo":"3","locationCd":"8566","showDate":"2025-02-26","filmCd":"001c0007202501","cinemaCd":"0000000000000002","cinemaName":"2号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1620,"saleOpen":false,"allocate":"true","dimensional":"3D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":32,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":35.0,"bookingFeeFlg":false,"filmDuration":144,"filmCode":"001c00072025","filmLongTitle":"哪吒之魔童闹海（数字3D）","filmShortTitle":"哪吒之魔童闹海（数字3D）","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"8566250226FH28BD","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"85662502268R6FL000","seqNo":"4","locationCd":"8566","showDate":"2025-02-26","filmCd":"00310011202501","cinemaCd":"0000000000000001","cinemaName":"1号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1720,"saleOpen":false,"allocate":"true","dimensional":"2D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":23,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":30.0,"bookingFeeFlg":false,"filmDuration":112,"filmCode":"003100112025","filmLongTitle":"诡才之道","filmShortTitle":"诡才之道","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"8566250226JT060D","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"85662502260N8PN8L6","seqNo":"4","locationCd":"8566","showDate":"2025-02-26","filmCd":"001c0007202501","cinemaCd":"0000000000000002","cinemaName":"2号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1900,"saleOpen":true,"allocate":"true","dimensional":"3D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":23,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":35.0,"bookingFeeFlg":false,"filmDuration":144,"filmCode":"001c00072025","filmLongTitle":"哪吒之魔童闹海（数字3D）","filmShortTitle":"哪吒之魔童闹海（数字3D）","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"856625022666N8ZT","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"856625022624J0P64X","seqNo":"5","locationCd":"8566","showDate":"2025-02-26","filmCd":"00110680202401","cinemaCd":"0000000000000001","cinemaName":"1号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":1930,"saleOpen":true,"allocate":"true","dimensional":"2D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":23,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":35.0,"bookingFeeFlg":false,"filmDuration":137,"filmCode":"001106802024","filmLongTitle":"唐探1900","filmShortTitle":"唐探1900","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"8566250226042RDV","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"8566250226T4468NNR","seqNo":"2","locationCd":"8566","showDate":"2025-02-26","filmCd":"001c0007202501","cinemaCd":"0000000000000003","cinemaName":"3号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":2000,"saleOpen":true,"allocate":"true","dimensional":"3D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":52,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":35.0,"bookingFeeFlg":false,"filmDuration":144,"filmCode":"001c00072025","filmLongTitle":"哪吒之魔童闹海（数字3D）","filmShortTitle":"哪吒之魔童闹海（数字3D）","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"856625022626RD40","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"8566250226FPF04XLN","seqNo":"5","locationCd":"8566","showDate":"2025-02-26","filmCd":"001c0007202501","cinemaCd":"0000000000000002","cinemaName":"2号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":2140,"saleOpen":true,"allocate":"true","dimensional":"3D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":32,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":35.0,"bookingFeeFlg":false,"filmDuration":144,"filmCode":"001c00072025","filmLongTitle":"哪吒之魔童闹海（数字3D）","filmShortTitle":"哪吒之魔童闹海（数字3D）","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"8566250226V6VH8N","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null},{"refSeqNo":"8566250226L4V0404D","seqNo":"6","locationCd":"8566","showDate":"2025-02-26","filmCd":"00310011202501","cinemaCd":"0000000000000001","cinemaName":"1号厅--遇3D影片建议自备或购买3D眼镜","showTimeInt":2200,"saleOpen":true,"allocate":"true","dimensional":"2D","throughId":null,"throughFlg":false,"throughSeq":0,"throughChildFlg":false,"childSessions":[],"pricePolicyId":"001","pricePolicyDesc":null,"freeSeatsCount":23,"performanceCD":"01","performanceName":null,"marketPrice":0.0,"leastPrice":30.0,"bookingFeeFlg":false,"filmDuration":112,"filmCode":"003100112025","filmLongTitle":"诡才之道","filmShortTitle":"诡才之道","filmEnglishTitle":null,"languageCd":"CN","languageName":"国语","filmCarryCd":"2","filmCarryName":"数字","cardDiscountAllowFlg":true,"showChannelCds":["BO","GPW","IDS","IVRS","KIOSK","MOBILE","MTW","NMW","TAOBAO","WAP","WEB","WEIBO","WEIXIN"],"sessionCode":"85662502262V6VPB","filmVerson":null,"firstShowflg":false,"starShowFlg":false,"filmSynopsis":null,"filmMainStars":null,"filmDirectedBy":null,"sortByFilmCd":null}]}}
     *
     * @param param
     * @return
     */
    public ApiResponse<SessionResponse> ticketGetSessions(ScheduleRequestCO param) {
        SessionRequest sessionRequest = new SessionRequest();
        sessionRequest.setLocationCd(param.getCinemaLinkId());
        //只能一天一天拿，后续可以改成循环
        sessionRequest.setShowDate(DateUtil.formatDate(param.getStartDate()));
        //这里的排期放映时间是个int，时+分。例如22:10，是2210
        String requestBody = request(sessionRequest, JynettyApiUriConstant.TICKET_GET_SESSIONS);
        ApiResponse<SessionResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<SessionResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 影厅
     * {"success":true,"error":null,"data":{"code":"1006","version":"1.0.0.1","serialNumber":"0016c82df8ac472280ef4a320395c1f9","result":0,"message":null,"halls":[{"cinemaCd":"0000000000000001","cinemaName":"1号厅--遇3D影片建议自备或购买3D眼镜","cinemaType":"N","cinemaTypeGM":null,"seatsCount":54},{"cinemaCd":"0000000000000002","cinemaName":"2号厅--遇3D影片建议自备或购买3D眼镜","cinemaType":"N","cinemaTypeGM":null,"seatsCount":64},{"cinemaCd":"0000000000000003","cinemaName":"3号厅--遇3D影片建议自备或购买3D眼镜","cinemaType":"N","cinemaTypeGM":null,"seatsCount":131}]}}
     *
     * @return
     */
    public ApiResponse<HallsResponse> ticketGetHalls(String cinemaId) {
        BaseRequest baseRequest = new BaseRequest();
        baseRequest.setLocationCd(cinemaId);
        String requestBody = request(baseRequest, JynettyApiUriConstant.TICKET_GET_HALLS);
        ApiResponse<HallsResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<HallsResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 静态座位图
     * 场区也在这里
     * {"success":true,"error":null,"data":{"code":"1009","version":"1.0.0.1","serialNumber":"5554b3993d99435abccd5696cc88d900","result":0,"message":null,"seatPlans":[{"effectiveDate":"2023-10-17T16:00:00.000+00:00","cinemaCd":"0000000000000001","sectionId":"0000000000000001","seats":[{"sectionId":"0000000000000001","rowId":"7","colId":"02","seatType":"N","rowNum":7,"colNum":2,"seatIsDamaged":true,"rank":"21","seatCode":"0000000000000297"},{"sectionId":"0000000000000001","rowId":"7","colId":"03","seatType":"N","rowNum":7,"colNum":3,"seatIsDamaged":true,"rank":"14","seatCode":"0000000000000298"},{"sectionId":"0000000000000001","rowId":"7","colId":"04","seatType":"N","rowNum":7,"colNum":4,"seatIsDamaged":true,"rank":"7","seatCode":"0000000000000299"},{"sectionId":"0000000000000001","rowId":"7","colId":"05","seatType":"N","rowNum":7,"colNum":5,"seatIsDamaged":true,"rank":"112","seatCode":"0000000000000300"},{"sectionId":"0000000000000001","rowId":"7","colId":"06","seatType":"N","rowNum":7,"colNum":6,"seatIsDamaged":true,"rank":"224","seatCode":"0000000000000301"},{"sectionId":"0000000000000001","rowId":"7","colId":"07","seatType":"N","rowNum":7,"colNum":7,"seatIsDamaged":true,"rank":"336","seatCode":"0000000000000302"},{"sectionId":"0000000000000001","rowId":"7","colId":"08","seatType":"N","rowNum":7,"colNum":8,"seatIsDamaged":true,"rank":"448","seatCode":"0000000000000303"},{"sectionId":"0000000000000001","rowId":"1","colId":"01","seatType":"N","rowNum":1,"colNum":1,"seatIsDamaged":false,"rank":"4","seatCode":"0000000000000250"},{"sectionId":"0000000000000001","rowId":"1","colId":"02","seatType":"N","rowNum":1,"colNum":2,"seatIsDamaged":false,"rank":"3","seatCode":"0000000000000251"},{"sectionId":"0000000000000001","rowId":"1","colId":"03","seatType":"N","rowNum":1,"colNum":3,"seatIsDamaged":false,"rank":"2","seatCode":"0000000000000252"},{"sectionId":"0000000000000001","rowId":"1","colId":"04","seatType":"N","rowNum":1,"colNum":4,"seatIsDamaged":false,"rank":"1","seatCode":"0000000000000253"},{"sectionId":"0000000000000001","rowId":"1","colId":"05","seatType":"N","rowNum":1,"colNum":5,"seatIsDamaged":false,"rank":"2","seatCode":"0000000000000254"},{"sectionId":"0000000000000001","rowId":"1","colId":"06","seatType":"N","rowNum":1,"colNum":6,"seatIsDamaged":false,"rank":"4","seatCode":"0000000000000255"},{"sectionId":"0000000000000001","rowId":"1","colId":"07","seatType":"N","rowNum":1,"colNum":7,"seatIsDamaged":false,"rank":"6","seatCode":"0000000000000256"},{"sectionId":"0000000000000001","rowId":"1","colId":"08","seatType":"N","rowNum":1,"colNum":8,"seatIsDamaged":false,"rank":"8","seatCode":"0000000000000257"},{"sectionId":"0000000000000001","rowId":"2","colId":"01","seatType":"N","rowNum":2,"colNum":1,"seatIsDamaged":false,"rank":"8","seatCode":"0000000000000258"},{"sectionId":"0000000000000001","rowId":"2","colId":"02","seatType":"N","rowNum":2,"colNum":2,"seatIsDamaged":false,"rank":"6","seatCode":"0000000000000259"},{"sectionId":"0000000000000001","rowId":"2","colId":"03","seatType":"N","rowNum":2,"colNum":3,"seatIsDamaged":false,"rank":"4","seatCode":"0000000000000260"},{"sectionId":"0000000000000001","rowId":"2","colId":"04","seatType":"N","rowNum":2,"colNum":4,"seatIsDamaged":false,"rank":"2","seatCode":"0000000000000261"},{"sectionId":"0000000000000001","rowId":"2","colId":"05","seatType":"N","rowNum":2,"colNum":5,"seatIsDamaged":false,"rank":"4","seatCode":"0000000000000262"},{"sectionId":"0000000000000001","rowId":"2","colId":"06","seatType":"N","rowNum":2,"colNum":6,"seatIsDamaged":false,"rank":"8","seatCode":"0000000000000263"},{"sectionId":"0000000000000001","rowId":"2","colId":"07","seatType":"N","rowNum":2,"colNum":7,"seatIsDamaged":false,"rank":"12","seatCode":"0000000000000264"},{"sectionId":"0000000000000001","rowId":"2","colId":"08","seatType":"N","rowNum":2,"colNum":8,"seatIsDamaged":false,"rank":"16","seatCode":"0000000000000265"},{"sectionId":"0000000000000001","rowId":"3","colId":"01","seatType":"N","rowNum":3,"colNum":1,"seatIsDamaged":false,"rank":"12","seatCode":"0000000000000266"},{"sectionId":"0000000000000001","rowId":"3","colId":"02","seatType":"N","rowNum":3,"colNum":2,"seatIsDamaged":false,"rank":"9","seatCode":"0000000000000267"},{"sectionId":"0000000000000001","rowId":"3","colId":"03","seatType":"N","rowNum":3,"colNum":3,"seatIsDamaged":false,"rank":"6","seatCode":"0000000000000268"},{"sectionId":"0000000000000001","rowId":"3","colId":"04","seatType":"N","rowNum":3,"colNum":4,"seatIsDamaged":false,"rank":"3","seatCode":"0000000000000269"},{"sectionId":"0000000000000001","rowId":"3","colId":"05","seatType":"N","rowNum":3,"colNum":5,"seatIsDamaged":false,"rank":"6","seatCode":"0000000000000270"},{"sectionId":"0000000000000001","rowId":"3","colId":"06","seatType":"N","rowNum":3,"colNum":6,"seatIsDamaged":false,"rank":"12","seatCode":"0000000000000271"},{"sectionId":"0000000000000001","rowId":"3","colId":"07","seatType":"N","rowNum":3,"colNum":7,"seatIsDamaged":false,"rank":"18","seatCode":"0000000000000272"},{"sectionId":"0000000000000001","rowId":"3","colId":"08","seatType":"N","rowNum":3,"colNum":8,"seatIsDamaged":false,"rank":"24","seatCode":"0000000000000273"},{"sectionId":"0000000000000001","rowId":"4","colId":"01","seatType":"N","rowNum":4,"colNum":1,"seatIsDamaged":false,"rank":"16","seatCode":"0000000000000274"},{"sectionId":"0000000000000001","rowId":"4","colId":"02","seatType":"N","rowNum":4,"colNum":2,"seatIsDamaged":false,"rank":"12","seatCode":"0000000000000275"},{"sectionId":"0000000000000001","rowId":"4","colId":"03","seatType":"N","rowNum":4,"colNum":3,"seatIsDamaged":false,"rank":"8","seatCode":"0000000000000276"},{"sectionId":"0000000000000001","rowId":"4","colId":"04","seatType":"N","rowNum":4,"colNum":4,"seatIsDamaged":false,"rank":"4","seatCode":"0000000000000277"},{"sectionId":"0000000000000001","rowId":"4","colId":"05","seatType":"N","rowNum":4,"colNum":5,"seatIsDamaged":false,"rank":"8","seatCode":"0000000000000278"},{"sectionId":"0000000000000001","rowId":"4","colId":"06","seatType":"N","rowNum":4,"colNum":6,"seatIsDamaged":false,"rank":"16","seatCode":"0000000000000279"},{"sectionId":"0000000000000001","rowId":"4","colId":"07","seatType":"N","rowNum":4,"colNum":7,"seatIsDamaged":false,"rank":"24","seatCode":"0000000000000280"},{"sectionId":"0000000000000001","rowId":"5","colId":"01","seatType":"N","rowNum":5,"colNum":1,"seatIsDamaged":false,"rank":"20","seatCode":"0000000000000281"},{"sectionId":"0000000000000001","rowId":"5","colId":"02","seatType":"N","rowNum":5,"colNum":2,"seatIsDamaged":false,"rank":"15","seatCode":"0000000000000282"},{"sectionId":"0000000000000001","rowId":"5","colId":"03","seatType":"N","rowNum":5,"colNum":3,"seatIsDamaged":false,"rank":"10","seatCode":"0000000000000283"},{"sectionId":"0000000000000001","rowId":"5","colId":"04","seatType":"N","rowNum":5,"colNum":4,"seatIsDamaged":false,"rank":"5","seatCode":"0000000000000284"},{"sectionId":"0000000000000001","rowId":"5","colId":"05","seatType":"N","rowNum":5,"colNum":5,"seatIsDamaged":false,"rank":"10","seatCode":"0000000000000285"},{"sectionId":"0000000000000001","rowId":"5","colId":"06","seatType":"N","rowNum":5,"colNum":6,"seatIsDamaged":false,"rank":"20","seatCode":"0000000000000286"},{"sectionId":"0000000000000001","rowId":"5","colId":"07","seatType":"N","rowNum":5,"colNum":7,"seatIsDamaged":false,"rank":"30","seatCode":"0000000000000287"},{"sectionId":"0000000000000001","rowId":"6","colId":"01","seatType":"N","rowNum":6,"colNum":1,"seatIsDamaged":false,"rank":"24","seatCode":"0000000000000288"},{"sectionId":"0000000000000001","rowId":"6","colId":"02","seatType":"N","rowNum":6,"colNum":2,"seatIsDamaged":false,"rank":"18","seatCode":"0000000000000289"},{"sectionId":"0000000000000001","rowId":"6","colId":"03","seatType":"N","rowNum":6,"colNum":3,"seatIsDamaged":false,"rank":"12","seatCode":"0000000000000290"},{"sectionId":"0000000000000001","rowId":"6","colId":"04","seatType":"N","rowNum":6,"colNum":4,"seatIsDamaged":false,"rank":"6","seatCode":"0000000000000291"},{"sectionId":"0000000000000001","rowId":"6","colId":"05","seatType":"N","rowNum":6,"colNum":5,"seatIsDamaged":false,"rank":"12","seatCode":"0000000000000292"},{"sectionId":"0000000000000001","rowId":"6","colId":"06","seatType":"N","rowNum":6,"colNum":6,"seatIsDamaged":false,"rank":"24","seatCode":"0000000000000293"},{"sectionId":"0000000000000001","rowId":"6","colId":"07","seatType":"N","rowNum":6,"colNum":7,"seatIsDamaged":false,"rank":"36","seatCode":"0000000000000294"},{"sectionId":"0000000000000001","rowId":"6","colId":"08","seatType":"N","rowNum":6,"colNum":8,"seatIsDamaged":false,"rank":"48","seatCode":"0000000000000295"},{"sectionId":"0000000000000001","rowId":"7","colId":"01","seatType":"N","rowNum":7,"colNum":1,"seatIsDamaged":true,"rank":"28","seatCode":"0000000000000296"}]}]}}
     */
    public ApiResponse<SeatPlanResponse> ticketGetSeatplan(SeatPlanRequestCO param) {
        SectionsRequest sectionsRequest = new SectionsRequest();
        sectionsRequest.setLocationCd(param.getCinemaLinkId());
        sectionsRequest.setCinemaCd(param.getHallCode());
        String requestBody = request(sectionsRequest, JynettyApiUriConstant.TICKET_GET_SEATPLAN);
        ApiResponse<SeatPlanResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<SeatPlanResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 场区
     * {"success":true,"error":null,"data":{"code":"1008","version":"1.0.0.1","serialNumber":"4fdfafd7c09d44ef9d08a75c08687619","result":0,"message":null,"sections":[{"sectionID":"0000000000000001","sectionName":"普通区"}]}}
     */
    //todo 场区不能单独获得，要与座位图一起
    public ApiResponse<SectionsResponse> ticketGetCinemaSections(String cinemaLinkId, String hallCode) {
        SectionsRequest sectionsRequest = new SectionsRequest();
        sectionsRequest.setLocationCd(cinemaLinkId);
        sectionsRequest.setCinemaCd(hallCode);
        //这个字段必须，是从座位图里获取到的"effectiveDate": "2023-10-17T16:00:00.000+00:00",与时区有关，这个17号按照东8区格式化之后其实是18号。否则拿不到数据
        sectionsRequest.setShowDate("2023-09-05");
        String requestBody = request(sectionsRequest, JynettyApiUriConstant.TICKET_GET_CINEMA_SECTIONS);
        ApiResponse<SectionsResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<SectionsResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 锁座
     * {"success":true,"error":null,"data":{"code":"1001","version":"1.0.0.1","serialNumber":"a63baf1619f042759c65bd717f3d0717","result":0,"message":null,"tempBookingId":"RO20250301171520243","seats":[{"rowId":"5","colId":"01","seatStatus":"T","workSationId":"WEB","createUserId":"TAOBAO","createDate":"2025-03-01 17:15:19","boLockSeat":true,"sectionID":null,"checkTicketFlg":false,"bookingId":null,"repositionSeatSuccess":true,"remark":"","seatCode":"","printFlg":false}]}}
     */
    @PostMapping("ticketLockSeats")
    public ApiResponse<RepositionSeatsResponse> ticketLockSeats(@RequestBody SeatLockRequestCO param) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        RepositionSeatsRequest repositionSeatsRequest = new RepositionSeatsRequest();
        repositionSeatsRequest.setLocationCd(param.getCinemaLinkId());
        repositionSeatsRequest.setShowDate(DateUtil.formatDate(param.getShowStartTime()));
        repositionSeatsRequest.setShowTime(Integer.valueOf(DateUtil.format(param.getShowStartTime(), "HHmm")));
        //排期编码
        repositionSeatsRequest.setFilmCd(param.getScheduleKey());
        repositionSeatsRequest.setCinemaCd(param.getHallCode());
        repositionSeatsRequest.setRequestUserId(finixxSettings.getChannelCd());
        repositionSeatsRequest.setRequestWorkStationId(finixxSettings.getUserName());
        repositionSeatsRequest.setTempBookingId(param.getPlatformOrderCode());
        repositionSeatsRequest.setBoBlock(false);
        repositionSeatsRequest.setThroughFlg(false);
        repositionSeatsRequest.setReleaseTime(30);
        repositionSeatsRequest.setChannelCd(repositionSeatsRequest.getRequestUserId());
        repositionSeatsRequest.setSectionId(param.getSectionCode());
        repositionSeatsRequest.setSeats(new ArrayList<>());
        repositionSeatsRequest.setSeatCodes(new ArrayList<>());
        //座位
        for (SeatLockItemRequestCO item : param.getOrderSeatList()) {
            repositionSeatsRequest.getSeatCodes().add(item.getSeatCode());
            repositionSeatsRequest.getSeats().add(item.getRolId() + ":" + item.getColId());
        }

        String requestBody = request(repositionSeatsRequest, JynettyApiUriConstant.TICKET_LOCK_SEATS);
        ApiResponse<RepositionSeatsResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<RepositionSeatsResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 释放锁座（参数与锁座一样）
     * {"success":true,"error":null,"data":{"code":"1003","version":"1.0.0.1","serialNumber":"470e5782f5934d42b2670fe2e6445428","result":0,"message":null,"tempBookingId":null,"seats":[{"rowId":"5","colId":"01","seatStatus":"F","workSationId":"","createUserId":"","createDate":"0001-01-01 00:00:00","boLockSeat":false,"sectionID":null,"checkTicketFlg":false,"bookingId":null,"repositionSeatSuccess":true,"remark":"","seatCode":"","printFlg":false}]}}
     */
    @PostMapping("ticketUnLockSeats")
    public ApiResponse<RepositionSeatsResponse> ticketUnLockSeats(@RequestBody SeatLockRequestCO param) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        RepositionSeatsRequest repositionSeatsRequest = new RepositionSeatsRequest();
        repositionSeatsRequest.setLocationCd(param.getCinemaLinkId());
        repositionSeatsRequest.setShowDate(DateUtil.formatDate(param.getShowStartTime()));
        repositionSeatsRequest.setShowTime(Integer.valueOf(DateUtil.format(param.getShowStartTime(), "HHmm")));
        //排期编码
        repositionSeatsRequest.setFilmCd(param.getScheduleKey());
        repositionSeatsRequest.setCinemaCd(param.getHallCode());
        repositionSeatsRequest.setRequestUserId(finixxSettings.getChannelCd());
        repositionSeatsRequest.setRequestWorkStationId(finixxSettings.getUserName());
        repositionSeatsRequest.setTempBookingId(param.getPlatformOrderCode());
        repositionSeatsRequest.setBoBlock(false);
        repositionSeatsRequest.setThroughFlg(false);
        repositionSeatsRequest.setReleaseTime(30);
        repositionSeatsRequest.setChannelCd(repositionSeatsRequest.getRequestUserId());
        repositionSeatsRequest.setSectionId(param.getSectionCode());
        repositionSeatsRequest.setSeats(new ArrayList<>());
        repositionSeatsRequest.setSeatCodes(new ArrayList<>());
        //座位
        for (SeatLockItemRequestCO item : param.getOrderSeatList()) {
            repositionSeatsRequest.getSeatCodes().add(item.getSeatCode());
            repositionSeatsRequest.getSeats().add(item.getRolId() + ":" + item.getColId());
        }

        String requestBody = request(repositionSeatsRequest, JynettyApiUriConstant.TICKET_UNLOCK_SEATS);
        ApiResponse<RepositionSeatsResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<RepositionSeatsResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 获取已售座位
     * {"success":true,"error":null,"data":{"code":"1013","version":"1.0.0.1","serialNumber":"687d2f13ffa649f695154340d8145c64","result":0,"message":null,"seats":[{"rowId":"2","colId":"01","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000258","printFlg":false},{"rowId":"2","colId":"02","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000259","printFlg":false},{"rowId":"2","colId":"03","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000260","printFlg":false},{"rowId":"2","colId":"04","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000261","printFlg":false},{"rowId":"2","colId":"05","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000262","printFlg":false},{"rowId":"2","colId":"06","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000263","printFlg":false},{"rowId":"2","colId":"07","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000264","printFlg":false},{"rowId":"2","colId":"08","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000265","printFlg":false},{"rowId":"4","colId":"01","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000274","printFlg":false},{"rowId":"4","colId":"02","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000275","printFlg":false},{"rowId":"4","colId":"03","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000276","printFlg":false},{"rowId":"4","colId":"04","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000277","printFlg":false},{"rowId":"4","colId":"05","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000278","printFlg":false},{"rowId":"4","colId":"06","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000279","printFlg":false},{"rowId":"4","colId":"07","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000280","printFlg":false},{"rowId":"6","colId":"01","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000288","printFlg":false},{"rowId":"6","colId":"02","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000289","printFlg":false},{"rowId":"6","colId":"03","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000290","printFlg":false},{"rowId":"6","colId":"04","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000291","printFlg":false},{"rowId":"6","colId":"05","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000292","printFlg":false},{"rowId":"6","colId":"06","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000293","printFlg":false},{"rowId":"6","colId":"07","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000294","printFlg":false},{"rowId":"6","colId":"08","seatStatus":"H","workSationId":"SD-20231031JRFA","createUserId":"MJQT","createDate":null,"boLockSeat":true,"sectionID":"0000000000000001","checkTicketFlg":false,"bookingId":"8566025022812380","repositionSeatSuccess":false,"remark":null,"seatCode":"0000000000000295","printFlg":false}]}}
     */
    @PostMapping("/ticketGetSessionSeats")
    public ApiResponse<SeatSalesResponse> ticketGetSessionSeats(@RequestBody SeatSalesRequestCO param) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        SeatsRequest seatsRequest = new SeatsRequest();
        seatsRequest.setShowDate(DateUtil.formatDate(param.getShowStartTime()));
        seatsRequest.setShowTime(Integer.valueOf(DateUtil.format(param.getShowStartTime(), "HHmm")));
        seatsRequest.setFilmCd(param.getScheduleKey());
        seatsRequest.setCinemaCd(param.getHallCode());
        seatsRequest.setSectionId(param.getSectionCode());
        seatsRequest.setLocationCd(param.getCinemaLinkId());
        seatsRequest.setCacheFlg(false);
        seatsRequest.setChannelCd(finixxSettings.getChannelCd());

        String requestBody = request(seatsRequest, JynettyApiUriConstant.TICKET_GET_SESSION_SEATS);
        ApiResponse<SeatSalesResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<SeatSalesResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 提交票务订单
     * {"success":true,"error":null,"data":{"code":"0104","version":"1.0.0.1","serialNumber":"beebabcd5c6648deae2ebf23e0138bd1","result":0,"message":null,"ticketBookingResult":{"bookingBills":[{"bookingId":"RO20250305182538889","tickets":[{"ticketNo":"530802010Oa0007","rowId":"5","colId":"01","result":0,"infoCode":"530802010Oa0007O+jkyRZ3HX/CeMwA7D99EkhhRgUnDtCAcGUcxB5Pu4dsYlK6v0i7nNEAPKnF/uoYWvV8GvMxGj/wyygEQwTnrwysbYUz2JmW1QWWdC5vU2HwMYI9GTKPGmaolaYk1lGholiYDLYBjzks/ZvuDKr7hkKVE/J4yR7rUHgpne5tPq8=","seatCode":"00000000000002810501","sectionId":null,"cinemaChannelFee":0.0,"thirdTicketFee":0.0}],"confirmId":"2025030545321825","verifyCode":"250305011806AMBN"}]},"posSaleResult":null}}
     *
     * @param model 请求入参
     * @return 订单详情
     * @throws UserFriendlyException 异常
     */
    @PostMapping("/tkSubmitOrder")
    public ApiResponse<OrderInfoResponseCO> tkSubmitOrder(@RequestBody OrderSubmitRequestCO model) {
        try {
            FinixxSettingsDTO finixxSettings = getFinixxSettings();
            String tokenStr = JSONObject.toJSONString(model, JSONWriter.Feature.IgnoreEmpty);
            String token = DigestUtil.md5Hex(tokenStr);
            BKBookingOrderRequest bookingOrderRequest = new BKBookingOrderRequest();
            //基础参数
            bookingOrderRequest.setMobilePhone(model.getMobile());
            bookingOrderRequest.setChannelCd(finixxSettings.getChannelCd());
            bookingOrderRequest.setLocationCd(model.getCinemaLinkId());
            bookingOrderRequest.setTokenNum(token);
            bookingOrderRequest.setSerialNumber(IdUtil.fastSimpleUUID());

            //影票订单参数
            BKTicketBookingRequest ticketBookingRequest = new BKTicketBookingRequest();
            //使用自渠上报编码（实际后面是否要更改看具体上报规则，以前使用的是WEIXIN用户，上报也是使用自渠）
            ticketBookingRequest.setSaleChannelCode(model.getCinemaCode());
            ticketBookingRequest.setSaleChannelName(model.getCinemaName());
            ticketBookingRequest.setExtJson("{'version':'1.0.0'}");

            ticketBookingRequest.setTransation(BookingTransaction.BUY_TICKET);
            ticketBookingRequest.setUserId(bookingOrderRequest.getChannelCd());
            //todo 工作站？先瞎给一个
            ticketBookingRequest.setWorkStationId(finixxSettings.getWorkSation());
            ticketBookingRequest.setOprnDate(DateTime.now().toDateStr());
            ticketBookingRequest.setShiftNo("0");
            ticketBookingRequest.setWriteShiftFlg(false);
            ticketBookingRequest.setPrintTicketFlg(false);
            ticketBookingRequest.setIncreaseFlg(true);
            ticketBookingRequest.setLeastPriceFlg(true);
            ticketBookingRequest.setSaleSpeed(new BigDecimal("0"));
            ticketBookingRequest.setLocationcd(bookingOrderRequest.getLocationCd());
            ticketBookingRequest.setGlobalOrderNo(null);
            ticketBookingRequest.setChannelCd(bookingOrderRequest.getChannelCd());
            ticketBookingRequest.setBookingBills(new ArrayList<>());

            BKBookingBillsRequest bookingBillsRequest = new BKBookingBillsRequest();
            bookingBillsRequest.setBookingId(model.getClocalOrderCode());
            bookingBillsRequest.setTempBookingId(model.getClocalOrderCode());
            bookingBillsRequest.setDeductionTimes("0");
            BKBookingRequest bookingRequest = new BKBookingRequest();
            bookingRequest.setThroughFlg(false);
            //本单服务费(影票参数累计)
            bookingRequest.setServiceFee(new BigDecimal("0"));
            //本单总额（影票参数累计）
            bookingRequest.setTotalCashPaid(new BigDecimal("0"));
            bookingRequest.setTotalCashChange(new BigDecimal("0"));
            bookingBillsRequest.setBooking(bookingRequest);
            bookingBillsRequest.setTickets(new ArrayList<>());
            //网络代售费支付
            bookingBillsRequest.setBookingFeePayment(null);
            BigDecimal webServiceFee = new BigDecimal("0");


            int seqNo = 1;
            for (OrderSeatRequestCO orderSeatRequestCO : model.getOrderSeatList()) {
                //本单影厅服务费
                bookingRequest.setServiceFee(bookingRequest.getServiceFee().add(orderSeatRequestCO.getHallServiceFee()));
                //本单总额
                bookingRequest.setTotalCashPaid(bookingRequest.getTotalCashPaid().add(orderSeatRequestCO.getSalePrice()));
                //本单网络代售费
                webServiceFee = webServiceFee.add(orderSeatRequestCO.getWebServiceFee());

                BKTicketsRequest ticketRequest = new BKTicketsRequest();
                ticketRequest.setBookingId(model.getClocalOrderCode());
                ticketRequest.setSeqNo(String.valueOf(seqNo++));
                ticketRequest.setSectionId(model.getSectionCode());
                //todo 开放平台用的seatCode-rolId-colId拼接的字符串又解析的。这里改用属性rolId与colId
                ticketRequest.setRowId(orderSeatRequestCO.getRolId());
                ticketRequest.setColId(orderSeatRequestCO.getColId());
                ticketRequest.setPriceType(finixxSettings.getPriceType());
                ticketRequest.setPriceAmt(orderSeatRequestCO.getSalePrice());
                ticketRequest.setPrintFlg(false);
                ticketRequest.setBookingFeeAmt(orderSeatRequestCO.getWebServiceFee());
                ticketRequest.setThirdTicketFee(orderSeatRequestCO.getWebServiceFee());
                ticketRequest.setCinemaChannelFee(new BigDecimal("0"));
                ticketRequest.setBookingFeeApplInd(orderSeatRequestCO.getHallServiceFeeType().getCode());
                ticketRequest.setServiceFee(orderSeatRequestCO.getHallServiceFee());
                ticketRequest.setMemberFlg(false);
                ticketRequest.setOriginalPrice(orderSeatRequestCO.getSettlePrice().toString());
                //每张票支付方式集合
                ticketRequest.setPayments(new ArrayList<>());
                //接入商
                BKPaymentsRequest paymentsRequestCrop = new BKPaymentsRequest();
                paymentsRequestCrop.setSeqNo(String.valueOf(1));
                //支付方式为接入商
                paymentsRequestCrop.setPaymentType("Corp");
                paymentsRequestCrop.setTotalAmtPaid(orderSeatRequestCO.getPaymentPrice());
                paymentsRequestCrop.setBaseAmt(orderSeatRequestCO.getPaymentPrice());
                paymentsRequestCrop.setMarking(new BigDecimal("0"));
                paymentsRequestCrop.setThroughFlg(false);
                paymentsRequestCrop.setRefundFlg(false);

                ticketRequest.getPayments().add(paymentsRequestCrop);
                //影院补贴
                if (orderSeatRequestCO.getSubsidyPrice() != null && orderSeatRequestCO.getSubsidyPrice().compareTo(new BigDecimal("0")) > 0) {
                    BKPaymentsRequest paymentsRequestCinema = new BKPaymentsRequest();
                    paymentsRequestCinema.setSeqNo(String.valueOf(seqNo++));
                    paymentsRequestCinema.setPaymentType("CinemaPay");
                    paymentsRequestCinema.setTotalAmtPaid(orderSeatRequestCO.getSubsidyPrice());
                    paymentsRequestCinema.setBaseAmt(orderSeatRequestCO.getSubsidyPrice());
                    paymentsRequestCinema.setMarking(new BigDecimal("0"));
                    paymentsRequestCinema.setThroughFlg(false);
                    paymentsRequestCinema.setRefundFlg(false);
                    paymentsRequestCinema.setAllowanceCd("00");
                    ticketRequest.getPayments().add(paymentsRequestCinema);
                }
                if (orderSeatRequestCO.getMemberCardPrice() != null && orderSeatRequestCO.getMemberCardPrice().compareTo(new BigDecimal("0")) > 0) {
                    BKPaymentsRequest paymentsRequestMember = new BKPaymentsRequest();
                    paymentsRequestMember.setSeqNo(String.valueOf(seqNo++));
                    paymentsRequestMember.setPaymentType("MemberCard");
                    paymentsRequestMember.setTotalAmtPaid(orderSeatRequestCO.getMemberCardPrice());
                    paymentsRequestMember.setBaseAmt(orderSeatRequestCO.getMemberCardPrice());
                    paymentsRequestMember.setMarking(new BigDecimal("0"));
                    paymentsRequestMember.setThroughFlg(false);
                    paymentsRequestMember.setRefundFlg(false);
                    paymentsRequestMember.setAllowanceCd("00");
                    paymentsRequestMember.setMemberCardFacadeCd(orderSeatRequestCO.getCardNo());
                    paymentsRequestMember.setMemberCardGradeId(orderSeatRequestCO.getCardGradeId());
                    paymentsRequestMember.setAkcMemberId(orderSeatRequestCO.getMemberId());
                    paymentsRequestMember.setSalesCd(finixxSettings.getChannelCd());
                    ticketRequest.getPayments().add(paymentsRequestMember);
                }
                //购买的影票
                bookingBillsRequest.getTickets().add(ticketRequest);
            }
            //网络代售费
            if (webServiceFee.compareTo(new BigDecimal("0")) > 0) {
                BKPaymentsRequest paymentsRequest = new BKPaymentsRequest();
                paymentsRequest.setSeqNo(String.valueOf(seqNo++));
                paymentsRequest.setPaymentType("Corp");
                paymentsRequest.setTotalAmtPaid(webServiceFee);
                paymentsRequest.setBaseAmt(webServiceFee);
                paymentsRequest.setMarking(new BigDecimal("0"));
                paymentsRequest.setThroughFlg(false);
                paymentsRequest.setRefundFlg(false);
                bookingBillsRequest.setBookingFeePayment(new ArrayList<>());
                bookingBillsRequest.getBookingFeePayment().add(paymentsRequest);
            }

            ticketBookingRequest.getBookingBills().add(bookingBillsRequest);
            //订票人信息
            BKPatronRequest patronRequest = new BKPatronRequest();
            patronRequest.setName(bookingOrderRequest.getChannelCd());
            patronRequest.setTelephoneNo(model.getMobile());
            patronRequest.setConfirmId(null);
            patronRequest.setBookflg("Y");
            ticketBookingRequest.setPatron(patronRequest);
            bookingOrderRequest.setTicketBooking(ticketBookingRequest);

            String requestBodyStr = JSONObject.toJSONString(bookingOrderRequest);
            System.out.println(requestBodyStr);
            String requestBody = request(bookingOrderRequest, JynettyApiUriConstant.BASIC_BOOKING_ORDER);
            ApiResponse<BookingOrderResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<BookingOrderResponse>>() {
            });
            if (!apiResponse.getSuccess()) {
                log.error("下单失败，responseBody={}", apiResponse);
                //不成功也并不意味着直接失败，需要自行根据单号查询订单信息来确认。需要多次轮询订单信息结果来确认，否则会出现丢单的情况。
                return ApiResponse.fail(apiResponse.getError());
            }
            Optional<BookingOrderBillsItemResponse> optionalBillItem = apiResponse.getData().getTicketBookingResult().getBookingBills()
                    .stream().filter(v -> v.getBookingId().equals(model.getClocalOrderCode())).findFirst();
            if (!optionalBillItem.isPresent()) {
                //不成功也并不意味着直接失败，需要自行根据单号查询订单信息来确认。需要多次轮询订单信息结果来确认，否则会出现丢单的情况。
                log.error("下单成功但返回结果订单号不匹配！bookingId：{}，responseBody={}", model.getClocalOrderCode(), apiResponse);
                return ApiResponse.fail(BOOKING_ID_NO_EQUALS.getCode(), "下单成功但订单号不匹配");
            }
            OrderInfoResponseCO result = new OrderInfoResponseCO();
            result.setOrderStatus(OrderStatusEnum.SUCCEED);
            result.setCloudOrderCode(model.getClocalOrderCode());
            result.setClocalOrderCode(optionalBillItem.get().getBookingId());
            result.setPrintCode(optionalBillItem.get().getConfirmId());
            result.setVerifyCode(optionalBillItem.get().getVerifyCode());
            result.setTicketList(new ArrayList<>());
            result.setPrintFlag(false);
            result.setPrintTime(null);
            result.setRefundTime(null);
//            ExtendInfoCO extend = new ExtendInfoCO();
//            extend.setChannleType(InterfaceChannelEnum.FINIXX.getCode());
//            extend.setDataType(DataTypeEnum.ORDER_INFO);
//            extend.setData(BeanUtil.beanToMap(bookingOrderResponse));
//            result.setExtendInfo(extend);
            optionalBillItem.get().getTickets().forEach(v -> {
                OrderTicketResponseCO ticket = new OrderTicketResponseCO();
                ticket.setTicketCode(v.getTicketNo());
                //如果上方找不到座位号则使用专资座位号做自行处理
                if (ticket.getSeatCode() == null) {
                    String seatInfo = v.getSeatCode().substring(0, v.getSeatCode().length() - 4);
                    String seatCode = StrUtil.format("{}-{}-{}", seatInfo, v.getRowId(), v.getColId());
                    ticket.setSeatCode(seatCode);
                }
                ticket.setZjbSeatCode(v.getSeatCode());
                ticket.setSectionCode(model.getSectionCode());
                ticket.setRow(v.getRowId());
                ticket.setColumn(v.getColId());
                ticket.setInfoCode(v.getInfoCode());
//                ticket.setExtendInfo(null);
                result.getTicketList().add(ticket);
            });
            log.info("出票成功{}", result);
            return ApiResponse.success(result);
        } catch (Exception e) {
            return ApiResponse.fail(new ApiErrorInfo(SystemErrorCode.SYSTEM_ERROR, e.getMessage()));
        }

    }

    public static void main(String[] args) {
        ApiResponse<BookingOrderResponse> apiResponse = JSON.parseObject("{\"success\":true,\"error\":null,\"data\":{\"code\":\"0104\",\"version\":\"1.0.0.1\",\"serialNumber\":\"3dbc7fe2d4a74996931e874e1bdcba35\",\"result\":0,\"message\":null,\"ticketBookingResult\":{\"bookingBills\":[{\"bookingId\":\"000001003903\",\"tickets\":[{\"ticketNo\":\"530802010PC000B\",\"rowId\":\"8\",\"colId\":\"13\",\"result\":0,\"infoCode\":\"530802010PC000BTjYoGtDSDdmL5J80vIg0lVuoHpyVCQ8yX9LA5XQ2za394dml0tXdifwmOh9+kiqYjWkPcns4fOx8LNq3Q2BBjr5g4GaJlDqqj/Xi26gAwxK4ZSRCdao1jv8/Elpg1UA8CcikASJQyjCieXuUezcuUmgKFJ5mUbjRGK0qqXt9+qc=\",\"seatCode\":\"00000000000004180813\",\"sectionId\":null,\"cinemaChannelFee\":0.0,\"thirdTicketFee\":0.0}],\"confirmId\":\"2025041228432653\",\"verifyCode\":\"250412012633FDTY\"}]},\"posSaleResult\":null}}", new TypeReference<ApiResponse<BookingOrderResponse>>() {
        });
        if (!apiResponse.getSuccess()) {
            log.error("下单失败，responseBody={}", apiResponse);
            //不成功也并不意味着直接失败，需要自行根据单号查询订单信息来确认。需要多次轮询订单信息结果来确认，否则会出现丢单的情况。
            //return ApiResponse.fail(apiResponse.getError());
        }
        Optional<BookingOrderBillsItemResponse> optionalBillItem = apiResponse.getData().getTicketBookingResult().getBookingBills()
                .stream().filter(v -> v.getBookingId().equals("000001003903")).findFirst();
        if (!optionalBillItem.isPresent()) {
            //不成功也并不意味着直接失败，需要自行根据单号查询订单信息来确认。需要多次轮询订单信息结果来确认，否则会出现丢单的情况。
            log.error("下单成功但返回结果订单号不匹配！bookingId：{}，responseBody={}", "model.getClocalOrderCode()", apiResponse);
            //return ApiResponse.fail(BOOKING_ID_NO_EQUALS.getCode(), "下单成功但订单号不匹配");
        }
        OrderInfoResponseCO result = new OrderInfoResponseCO();
        result.setOrderStatus(OrderStatusEnum.SUCCEED);
        result.setCloudOrderCode("model.getClocalOrderCode()");
        result.setClocalOrderCode(optionalBillItem.get().getBookingId());
        result.setPrintCode(optionalBillItem.get().getConfirmId());
        result.setVerifyCode(optionalBillItem.get().getVerifyCode());
        result.setTicketList(new ArrayList<>());
        result.setPrintFlag(false);
        result.setPrintTime(null);
        result.setRefundTime(null);
//            ExtendInfoCO extend = new ExtendInfoCO();
//            extend.setChannleType(InterfaceChannelEnum.FINIXX.getCode());
//            extend.setDataType(DataTypeEnum.ORDER_INFO);
//            extend.setData(BeanUtil.beanToMap(bookingOrderResponse));
//            result.setExtendInfo(extend);
        optionalBillItem.get().getTickets().forEach(v -> {
            OrderTicketResponseCO ticket = new OrderTicketResponseCO();
            ticket.setTicketCode(v.getTicketNo());
            //如果上方找不到座位号则使用专资座位号做自行处理
            if (ticket.getSeatCode() == null) {
                String seatInfo = v.getSeatCode().substring(0, v.getSeatCode().length() - 4);
                String seatCode = StrUtil.format("{}-{}-{}", seatInfo, v.getRowId(), v.getColId());
                ticket.setSeatCode(seatCode);
            }
            ticket.setZjbSeatCode(v.getSeatCode());
            ticket.setSectionCode("model.getSectionCode()");
            ticket.setRow(v.getRowId());
            ticket.setColumn(v.getColId());
            ticket.setInfoCode(v.getInfoCode());
//                ticket.setExtendInfo(null);
            result.getTicketList().add(ticket);
        });
        System.out.println(result);
    }

    /**
     * 订单信息
     * {"success":true,"error":null,"data":{"code":"1048","version":"1.0.0.1","serialNumber":"17e1b13a3b964d00aff5b61097b60c07","result":0,"message":null,"order":{"bookingId":"RO20250305182538889","hallName":"1号厅--遇3D影片建议自备或购买3D眼镜","hallCode":"0000000000000001","startDateTime":"2025-03-05T13:30:00.000+00:00","throughFlg":false,"printNo":"2025030545321825","verifyCode":"250305011806AMBN","sessionCode":"85662503056420T6","createDateTime":"2025-03-05T10:42:19.000+00:00","sectionId":"0000000000000001"},"seats":[{"ticketNo":"530802010Oa0007","seatCode":"0000000000000281","rowId":"5","colId":"01","printFlg":false,"printDateTime":null,"refundFlg":false,"refundDateTime":null,"price":35.0}],"films":[{"code":"001b00072025","name":"哪吒之魔童闹海","duration":144,"seqNo":1}]}}
     *
     * @param model 入参
     * @return ApiResponse<OrderInfoResponseCO>
     * @throws UserFriendlyException 异常
     */
    @PostMapping("info")
    public ApiResponse<OrderInfoResponseCO> info(@RequestBody OrderInfoRequestCO model) {
        try {
            QueryOrderRequest queryOrderRequest = new QueryOrderRequest();
            queryOrderRequest.setBookingId(model.getCloudOrderCode());
            queryOrderRequest.setLocationCd(model.getCinemaLinkId());
            String requestBody = request(queryOrderRequest, JynettyApiUriConstant.TICKET_QUERY_ORDER);
            ApiResponse<QueryOrderResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<QueryOrderResponse>>() {
            });
            if (!apiResponse.getSuccess()) {
                return ApiResponse.fail(apiResponse.getError());
            }
            QueryOrderResponse queryOrderResponse = apiResponse.getData();
            if (queryOrderResponse == null || queryOrderResponse.getOrder() == null || !queryOrderResponse.getOrder().getBookingId().equals(model.getCloudOrderCode())) {
                log.error("查询订单成功但返回结果订单号不匹配！bookingId：{}，responseBody={}", model.getCloudOrderCode(), apiResponse);
                return ApiResponse.fail(BOOKING_ID_NO_EQUALS.getCode(), "查单成功但订单号不匹配");
            }
            return ApiResponse.success(buildQueryOrderInfo(queryOrderResponse));
        } catch (Exception e) {
            return ApiResponse.fail(new ApiErrorInfo(SystemErrorCode.SYSTEM_ERROR, e.getMessage()));
        }
    }

    /**
     * 构建查询订单返回结果
     *
     * @param queryOrderResponse 查单结果
     * @return ConfirmOrderMixResponseBO
     */
    private static @NotNull OrderInfoResponseCO buildQueryOrderInfo(QueryOrderResponse queryOrderResponse) {
        OrderInfoResponseCO orderInfoResponseCO = new OrderInfoResponseCO();
        orderInfoResponseCO.setOrderStatus(OrderStatusEnum.SUCCEED);
        orderInfoResponseCO.setCloudOrderCode(queryOrderResponse.getOrder().getBookingId());
        orderInfoResponseCO.setClocalOrderCode(queryOrderResponse.getOrder().getBookingId());
        orderInfoResponseCO.setPrintCode(queryOrderResponse.getOrder().getPrintNo());
        orderInfoResponseCO.setVerifyCode(queryOrderResponse.getOrder().getVerifyCode());
        orderInfoResponseCO.setTicketList(new ArrayList<>());
        for (OrderSeatsItemResponse v : queryOrderResponse.getSeats()) {
            OrderTicketResponseCO ticket = new OrderTicketResponseCO();
            ticket.setTicketCode(v.getTicketNo());
            ticket.setZjbSeatCode(StrUtil.format("{}{}{}", v.getSeatCode(), StrUtil.padPre(v.getRowId(), 2, "0"), StrUtil.padPre(v.getColId(), 2, "0")));
            ticket.setSectionCode(queryOrderResponse.getOrder().getSectionId());
            ticket.setRow(v.getRowId());
            ticket.setColumn(v.getColId());
            ticket.setInfoCode(null);
//            ticket.setExtendInfo(null);
            orderInfoResponseCO.getTicketList().add(ticket);
            orderInfoResponseCO.setPrintFlag(v.getPrintFlg());
            if (v.getPrintDateTime() != null) {
                orderInfoResponseCO.setPrintTime(v.getPrintDateTime());
            }
            if (v.getRefundFlg()) {
                orderInfoResponseCO.setOrderStatus(OrderStatusEnum.REFUNDED);
                orderInfoResponseCO.setRefundTime(v.getRefundDateTime());
            }
        }
        return orderInfoResponseCO;
    }

    /**
     * 影票订单退款
     * {"success":true,"error":null,"data":{"code":"1024","version":"1.0.0.1","serialNumber":"213bcc952d20404db521296f77774806","result":0,"message":null}}
     *
     * @param model 请求入参
     * @return 返回退票结果
     * @throws UserFriendlyException 异常
     */
    @PostMapping("/tkRefund")
    public ApiResponse<RefundOrderResponseCO> tkRefund(@RequestBody OrderRefundRequestCO model) {
        try {
            FinixxSettingsDTO finixxSettings = getFinixxSettings();
            String tokenStr = JSONObject.toJSONString(model, JSONWriter.Feature.IgnoreEmpty);
            String token = DigestUtil.md5Hex(tokenStr);
            RefundRequest refundRequest = new RefundRequest();
            refundRequest.setBookingId(model.getCloudOrderCode());
            refundRequest.setUserId(finixxSettings.getChannelCd());
            refundRequest.setWorkStationId(refundRequest.getWorkStationId());
            refundRequest.setOprnDate(DateTime.now().toDateStr());
            refundRequest.setShiftNo("1");
            refundRequest.setSystemCd(refundRequest.getUserId());
            refundRequest.setReasonCd("null");
            refundRequest.setWriteShiftFlg(false);
            refundRequest.setLocationCd(model.getCinemaLinkId());
            refundRequest.setTokenNum(token);
            refundRequest.setTickets(new ArrayList<>());
            for (OrderRefundSeatRequestCO refundTicket : model.getTickets()) {
                RefundTicketsRequest refundTicketsRequest = new RefundTicketsRequest();
                refundTicketsRequest.setTicketNo(refundTicket.getTicketNo());
                refundTicketsRequest.setRefundPayments(new ArrayList<>());
                RefundPaymentsRequest refundPaymentsCorp = new RefundPaymentsRequest();
                refundPaymentsCorp.setSeqNo("1");
                refundPaymentsCorp.setRefundType("Corp");
                refundTicketsRequest.getRefundPayments().add(refundPaymentsCorp);
                if (refundTicket.getSubsidyFlag()) {
                    RefundPaymentsRequest refundPaymentsCinemaPay = new RefundPaymentsRequest();
                    refundPaymentsCinemaPay.setSeqNo("2");
                    refundPaymentsCinemaPay.setRefundType("CinemaPay");
                    refundTicketsRequest.getRefundPayments().add(refundPaymentsCinemaPay);
                }
                if (refundTicket.getMemberCardFlag()) {
                    RefundPaymentsRequest refundPaymentsCinemaPay = new RefundPaymentsRequest();
                    refundPaymentsCinemaPay.setSeqNo("3");
                    refundPaymentsCinemaPay.setRefundType("MemberCard");
                    refundPaymentsCinemaPay.setCardFacadeCd(refundTicket.getCardNo());
                    refundPaymentsCinemaPay.setCardGradeId(refundTicket.getCardGradeId());
                    refundPaymentsCinemaPay.setCardLocationCd(model.getCinemaLinkId());
                    refundPaymentsCinemaPay.setSalesCd(finixxSettings.getChannelCd());
                    refundPaymentsCinemaPay.setAkcMemberId("30000303");
                    refundPaymentsCinemaPay.setAllowanceCd("00");
                    //refundTicketsRequest.getRefundPayments().add(refundPaymentsCinemaPay);
                }
                refundRequest.getTickets().add(refundTicketsRequest);
            }
            String requestBody = request(refundRequest, JynettyApiUriConstant.TICKET_REFUND);
            ApiResponse<RefundResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<RefundResponse>>() {
            });
            if (!apiResponse.getSuccess()) {
                return ApiResponse.fail(apiResponse.getError());
            }
            RefundResponse refundResponse = apiResponse.getData();
            RefundOrderResponseCO refundOrder = new RefundOrderResponseCO();
            refundOrder.setRefundTime(refundResponse.getRefundTime());
            return ApiResponse.success(refundOrder);
        } catch (Exception e) {
            return ApiResponse.fail(new ApiErrorInfo(SystemErrorCode.SYSTEM_ERROR, e.getMessage()));
        }
    }

    /**
     * 会员卡信息
     * {"success":true,"error":null,"data":{"code":"2001","version":"1.0.0.1","serialNumber":"0a010475bdb6428db8ef21b705343157","result":0,"message":null,"memberCard":{"code":null,"version":null,"serialNumber":null,"result":null,"message":null,"facadeCD":"30000303","oldMemberID":null,"memberID":"30000303","password":"E10ADC3949BA59ABBE56E057F20F883E","avaiFlag":true,"usePolicyID":"8","usePolicyDesc":"8","balance":110.0,"type":"C","state":"N","gradeID":"8","gradeDesc":"微信在线5折","cumulationMarking":0.0,"tradeMarking":0.0,"upgradeMarking":0.0,"addmoneyTM":2.0,"consumeUpgradeTM":0.0,"firstDate":"","lastDate":"","invalidationDate":"2045-03-04T16:00:00.000+00:00","consumePolicyID":"8","relationPass":null,"relationFlag":"N","relationDate":"","locationCD":"8566","locationDesc":"云南普洱墨江电影院","noPassFlag":false,"passwordFlag":"N","birthGiftLastDate":"","balanceTimes":0.0,"companyCD":null,"salesCD":null,"groupFlag":false,"pointDiscount":1.0,"upgradePolicyCD":"4","remark":" 普通卡, 凭密码消费，可充值型","consumePolicyDesc":"微信在线5折","ccbreplace":"N","ccbflag":false,"icbcflag":false},"member":{"address":null,"name":"zhangchengyi","mobilePhone":"13800138000","phone":null,"memberID":"30000303","postCode":null,"mailAddress":null,"nation":null,"photo":null,"birthDate":"1988-09-08T15:00:00.000+00:00","needNews":"0","sex":"男","nativePlace":null,"registerDate":"2025-03-04T16:00:00.000+00:00","IDType":"身份证","IDCard":"110181198809092212"},"cardPre":{"type":"C","locationCD":"8566","flowDescription":null,"usePloicyID":"8","meDium":"NO","specialID":"01","flow":"W","cardFaceFee":0.0,"reUseFlag":false,"reSellFlag":false,"gradePolicyID":"8","facadeCD":"30000303","serialCD":null,"consumePolicyID":"8","levelForeverFlag":false,"defaultMarking":0.0},"gradePolicyDtls":{"gradeLevel":8,"holdDeline":0,"levelGroup":0,"posDayAmt":0,"cosumeTM":0,"ticketDayNum":0,"ticketDayAmt":0,"cosumeDeline":0,"ticketShowNum":0,"totalTicketNum":0,"totalTicketFilmNum":0,"ticketMonthNum":0,"cinemaEditFlag":"true","ticketFilmDayNum":0,"gradeID":"8","gradeDesc":"微信在线5折","relationUsePolicyID":"8","editPolicyFlag":"false","upgradePolicyCD":"4"},"usePolicyDtls":{"koiskFlag":false,"webFlag":false,"wapFlag":false,"maxTicketShow":99,"boflag":true,"boCashFlag":false,"maxTicketDay":99,"validityDate":240,"ismsFlag":false,"posCashFlag":false,"minInAmt":0,"extensionMarkingFlag":false,"addExtensionFlag":false,"extensionUseFlag":false,"posNoBalanceUseFlag":false,"cashMarkingFlag":false,"useChannelCDList":["BO"],"addExtensionAmt":0,"useLocationList":[{"value":"云南普洱墨江电影院","key":"8566","isEnable":false}],"extensionUseDisFlag":false,"extensionBookingFlag":false,"noBalanceUseFlag":false,"cinemaEditFlag":false,"usePolicyPlace":[{"cinemaType":"N","cinemaTypeUseFlag":"true","cinemaTypeDesc":"普通厅"}],"fee":0.0,"membershipFee":0.0,"usePolicyID":"8","usePolicyDesc":"8"}}}
     *
     * @param model 请求入参
     * @return ApiResponse<MemberCardInfoCO>
     */
    @PostMapping("memberCardInfo")
    public ApiResponse<CardInfoResponseCO> memberCardInfo(@RequestBody CardInfoRequestCO model) {
        CardInfoRequest cardInfoRequest = new CardInfoRequest();
        cardInfoRequest.setCardLocationCd(model.getCinemaLinkId());
        cardInfoRequest.setCardFacadeCd(model.getCardNo());
        cardInfoRequest.setLocationCd(model.getCinemaLinkId());
        String requestBody = request(cardInfoRequest, JynettyApiUriConstant.CARD_INFO);
        ApiResponse<CardInfoResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<CardInfoResponse>>() {
        });
        if (!apiResponse.getSuccess()) {
            return ApiResponse.fail(apiResponse.getError());
        }
        CardInfoResponse cardInfoResponse = apiResponse.getData();
        CardInfoResponseCO cardResponseInfo = new CardInfoResponseCO();
        cardResponseInfo.setMemberName(cardInfoResponse.getMember().getName());
        cardResponseInfo.setIdCardType(cardInfoResponse.getMember().getIDType());
        cardResponseInfo.setIdCardNo(cardInfoResponse.getMember().getIDCard());
        cardResponseInfo.setBirthday(cardInfoResponse.getMember().getBirthDate());
        cardResponseInfo.setMobilePhone(cardInfoResponse.getMember().getMobilePhone());
        cardResponseInfo.setSex(cardInfoResponse.getMember().getSex());
        cardResponseInfo.setRegisterDate(cardInfoResponse.getMember().getRegisterDate());
        cardResponseInfo.setCardNo(cardInfoResponse.getMemberCard().getFacadeCD());
        cardResponseInfo.setPassword(cardInfoResponse.getMemberCard().getPassword());
        cardResponseInfo.setMarking(cardInfoResponse.getMemberCard().getCumulationMarking());
        //次卡和普通储值卡区分
        cardResponseInfo.setCardType(cardInfoResponse.getMemberCard().getUpgradePolicyCD().equals("3") ? "times" : "normal");
        cardResponseInfo.setBalance(cardResponseInfo.getCardType().equals("normal") ? cardInfoResponse.getMemberCard().getBalance() : cardInfoResponse.getMemberCard().getBalanceTimes());

        cardResponseInfo.setEnabledRechargeFlag(cardInfoResponse.getMemberCard().getType().equalsIgnoreCase("C"));
        cardResponseInfo.setEnabledFlag(cardInfoResponse.getMemberCard().getAvaiFlag() && cardInfoResponse.getMemberCard().getState().equalsIgnoreCase("N"));
        cardResponseInfo.setInvalidationDate(cardInfoResponse.getMemberCard().getInvalidationDate());
        cardResponseInfo.setCinemaLinkId(cardInfoResponse.getMemberCard().getLocationCD());
        cardResponseInfo.setCinemaName(cardInfoResponse.getMemberCard().getLocationDesc());
        cardResponseInfo.setGradeId(cardInfoResponse.getMemberCard().getGradeID());
        cardResponseInfo.setGradeName(cardInfoResponse.getMemberCard().getGradeDesc());
        cardResponseInfo.setUsePolicyId(cardInfoResponse.getMemberCard().getUsePolicyID());
        cardResponseInfo.setCardRemark(cardInfoResponse.getMemberCard().getRemark());
        cardResponseInfo.setMinRechargeAmount(cardInfoResponse.getUsePolicyDtls().getMinInAmt());
        cardResponseInfo.setMaxTicketDay(cardInfoResponse.getUsePolicyDtls().getMaxTicketDay());
        cardResponseInfo.setMaxTicketShow(cardInfoResponse.getUsePolicyDtls().getMaxTicketShow());
        cardResponseInfo.setNoBalanceUseTicketFlag(cardInfoResponse.getUsePolicyDtls().getNoBalanceUseFlag());
        cardResponseInfo.setNoBalanceUseGoodsFlag(cardInfoResponse.getUsePolicyDtls().getPosNoBalanceUseFlag());
        cardResponseInfo.setExtensionUseFlag(cardInfoResponse.getUsePolicyDtls().getExtensionUseFlag());
        cardResponseInfo.setTicketCashFlag(cardInfoResponse.getUsePolicyDtls().getBoCashFlag());
        cardResponseInfo.setGoodsCashFlag(cardInfoResponse.getUsePolicyDtls().getPosCashFlag());
        //可用影厅类型
        cardResponseInfo.setUseCinemaTypes(new ArrayList<>());
        for (UsePolicyPlaceResponse usePolicyPlaceResponse : cardInfoResponse.getUsePolicyDtls().getUsePolicyPlace()) {
            CardUseCodeNameCO cardUseCodeName = new CardUseCodeNameCO();
            cardUseCodeName.setCode(usePolicyPlaceResponse.getCinemaType());
            cardUseCodeName.setName(usePolicyPlaceResponse.getCinemaTypeDesc());
            cardResponseInfo.getUseCinemaTypes().add(cardUseCodeName);
        }
        //可用影院列表
        cardResponseInfo.setUseCinemas(new ArrayList<>());
        for (UseLocationResponse useLocationResponse : cardInfoResponse.getUsePolicyDtls().getUseLocationList()) {
            CardUseCodeNameCO cardUseCodeName = new CardUseCodeNameCO();
            cardUseCodeName.setCode(useLocationResponse.getKey());
            cardUseCodeName.setName(useLocationResponse.getValue());
            cardResponseInfo.getUseCinemas().add(cardUseCodeName);
        }
        //可用渠道列表
        cardResponseInfo.setUseChannels(cardInfoResponse.getUsePolicyDtls().getUseChannelCDList());
        return ApiResponse.success(cardResponseInfo);

    }

    /**
     * 会员卡充值
     * {"success":true,"error":null,"data":{"code":"2018","version":"1.0.0.1","serialNumber":"20c68b0221124ac7b44c562c7d298711","result":0,"message":null,"totalAddCount":1,"totalAddMoney":10.0,"cardAddMoney":[{"facadeCD":"30000303","addID":"CR20250308164237694","getMarking":0.0,"balance":110.0,"invalidationDate":"2045-03-05 16:40:02","cumulationMarking":0.0,"tradeMarking":0.0,"upgradeMarking":0.0,"balanceTimes":0,"cardAddGetWallet":{"code":null,"version":null,"serialNumber":null,"result":0,"message":null,"getWalletResult":3205,"cardGetWalletList":[]}}],"cardAddResultNode":[],"walletResultList":[]}}
     *
     * @param model 请求入参
     * @return ApiResponse<RechargeResponseCO>
     */
    @PostMapping("memberCardRecharge")
    public ApiResponse<RechargeResponseCO> memberCardRecharge(@RequestBody RechargeRequestCO model) {
        String tokenStr = JSONObject.toJSONString(model, JSONWriter.Feature.IgnoreEmpty);
        String token = DigestUtil.md5Hex(tokenStr);
        CardAddMoneyRequest cardAddMoneyRequest = buildCardAddMoneyRequest(model, token);
        String requestBody = request(cardAddMoneyRequest, JynettyApiUriConstant.CARD_ADD_MONEY);
        ApiResponse<CardAddMoneyResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<CardAddMoneyResponse>>() {
        });
        if (!apiResponse.getSuccess()) {
            return ApiResponse.fail(apiResponse.getError());
        }
        CardAddMoneyResponse cardAddMoneyResponse = apiResponse.getData();
        if (cardAddMoneyResponse.getCardAddMoney() == null || cardAddMoneyResponse.getCardAddMoney().isEmpty()) {
            return ApiResponse.fail(new ApiErrorInfo(CHARGE_ERROR));
        }
        Optional<CardAddMoneyItemResponse> cardAddMoneyOptional = cardAddMoneyResponse.getCardAddMoney()
                .stream().filter(v -> v.getFacadeCD().equals(model.getCardNo())).findFirst();
        if (!cardAddMoneyOptional.isPresent()) {
            return ApiResponse.fail(new ApiErrorInfo(CHARGE_ERROR));
        }
        RechargeResponseCO rechargeResponse = new RechargeResponseCO();
        rechargeResponse.setCloudOrderCode(model.getCloudOrderCode());
        rechargeResponse.setClocalOrderCode(cardAddMoneyOptional.get().getAddID());
        rechargeResponse.setCardNo(cardAddMoneyOptional.get().getFacadeCD());
        rechargeResponse.setRechargeAmount(model.getRechargeAmount());
        rechargeResponse.setBalance(cardAddMoneyOptional.get().getBalanceTimes() > 0 ? Convert.toBigDecimal(cardAddMoneyOptional.get().getBalanceTimes()) : cardAddMoneyOptional.get().getBalance());
        rechargeResponse.setMarking(cardAddMoneyOptional.get().getGetMarking());
        if (!cardAddMoneyResponse.getWalletResultList().isEmpty()) {
            rechargeResponse.setGiftError(StrUtil.join("；", cardAddMoneyResponse.getWalletResultList()));
        }
        rechargeResponse.setGiftDesc(null);
        if (!cardAddMoneyOptional.get().getCardAddGetWallet().getCardGetWalletList().isEmpty()) {
            rechargeResponse.setGiftDesc("");
            for (CardGetWalletListItemResponse cardGetWalletListItemResponse : cardAddMoneyOptional.get().getCardAddGetWallet().getCardGetWalletList()) {
                rechargeResponse.setGiftDesc(rechargeResponse.getGiftDesc() + cardGetWalletListItemResponse.getGiftTypeDesc() + "*" + cardGetWalletListItemResponse.getGiftCount() + "；");
            }
        }
        return ApiResponse.success(rechargeResponse);
    }

    /**
     * 组装会员卡充值请求体
     *
     * @param model 入参
     * @param token TOKEN
     * @return CardAddMoneyRequest
     */
    private @NotNull CardAddMoneyRequest buildCardAddMoneyRequest(RechargeRequestCO model, String token) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        CardAddMoneyRequest cardAddMoneyRequest = new CardAddMoneyRequest();
        cardAddMoneyRequest.setTokenNum(token);
        cardAddMoneyRequest.setUserID(finixxSettings.getChannelCd());
        cardAddMoneyRequest.setBeginFacadeCD(model.getCardNo());
        cardAddMoneyRequest.setEndFacadeCD(model.getCardNo());
        cardAddMoneyRequest.setAddMoney(model.getRechargeAmount());
        cardAddMoneyRequest.setSellLocationCD(model.getCinemaLinkId());
        cardAddMoneyRequest.setAddLocationCD(model.getCinemaLinkId());
        cardAddMoneyRequest.setPaymentType(model.getPaymentType().getCode());
        cardAddMoneyRequest.setPaymentName(model.getPaymentType().getName());
        cardAddMoneyRequest.setAddModule(cardAddMoneyRequest.getUserID());
        cardAddMoneyRequest.setDiscount(new BigDecimal("0"));
        cardAddMoneyRequest.setPaymentNO(model.getPaymentNo());
        cardAddMoneyRequest.setFingerFlag("N");
        cardAddMoneyRequest.setBatchAdd(false);
        cardAddMoneyRequest.setBatchMode(0);
        cardAddMoneyRequest.setWorkstation(cardAddMoneyRequest.getUserID());
        cardAddMoneyRequest.setSaleSpeed(new BigDecimal("0"));
        cardAddMoneyRequest.setAddReason(model.getRechargeReason());
        cardAddMoneyRequest.setWriteShiftFlag(false);
        cardAddMoneyRequest.setAddMoneyID(model.getCloudOrderCode());
        cardAddMoneyRequest.setLocationCd(model.getCinemaLinkId());
        return cardAddMoneyRequest;
    }

    /**
     * 组装发卡信息结果
     *
     * @param cardSellInfoResponse 佳影发卡返回信息
     * @return CardSellInfoResponseCO
     */
    private static @NotNull <T extends CardSellInfoResponseCO> T buildSellInfoResponse(CardSellInfoResponse cardSellInfoResponse, Class<T> clazz) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        T result = clazz.getDeclaredConstructor().newInstance();
        result.setCardNo(cardSellInfoResponse.getFacadeCD());
        result.setGradeId(cardSellInfoResponse.getGradeID());
        result.setGradeName(cardSellInfoResponse.getGradeDesc());
        result.setUsePolicyId(cardSellInfoResponse.getUsePolicyID());
        result.setInvalidationDate(cardSellInfoResponse.getValid());
        result.setCardType(cardSellInfoResponse.getUpgradeCD().equals("3") ? "times" : "normal");
        result.setEnabledRechargeFlag(cardSellInfoResponse.getCardType().equalsIgnoreCase("C"));
        result.setMinRechargeAmount(cardSellInfoResponse.getLeastAdd());
        result.setMarking(cardSellInfoResponse.getDefaultMarking());
        return result;
    }

    /**
     * 注册会员卡
     * {"success":true,"error":null,"data":{"code":"2015","version":"1.0.0.1","serialNumber":"ce07bc334103442595a1e1dd368b6160","result":0,"message":null,"facadeCD":"30000363","gradeID":"8","gradeDesc":"微信在线5折","upgradeCD":"4","discount":100.0,"consumeTM":0,"valid":"2045-03-08T08:41:07.000+00:00","cardType":"C","leastAdd":0.0,"usePolicyID":"8","usePolicyDesc":"8","consumePolicyID":"8","levelForeverFlag":false,"prefabricatedCinema":"云南普洱墨江电影院","defaultMarking":0,"parValue":0.0,"userName":null,"documentNO":null,"birthday":null,"mobile":null,"phone":null,"email":null,"address":null,"postCode":null,"sex":null,"fee":0.0,"exchangeFee":0.0,"membershipFee":0.0}}
     *
     * @param model 入参
     * @return ApiResponse<CardRegisterResponseCO>
     */
    @PostMapping("memberCardRegister")
    public ApiResponse<CardRegisterResponseCO> memberCardRegister(@RequestBody CardRegisterRequestCO model) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        CardSellInfoRequest cardSellInfoRequest = new CardSellInfoRequest();
        cardSellInfoRequest.setNoCardFlag("Y");
        cardSellInfoRequest.setGradeID(model.getGradeId());
        cardSellInfoRequest.setLocationCd(model.getCinemaLinkId());
        String sellInfoRequestBody = request(cardSellInfoRequest, JynettyApiUriConstant.CARD_SELL_INFO);
        ApiResponse<CardSellInfoResponse> sellInfoApiResponse = JSON.parseObject(sellInfoRequestBody, new TypeReference<ApiResponse<CardSellInfoResponse>>() {
        });
        if (!sellInfoApiResponse.getSuccess()) {
            return ApiResponse.fail(sellInfoApiResponse.getError());
        }
        //预制卡信息
        CardSellInfoResponse cardSellInfoResponse = sellInfoApiResponse.getData();
        //开卡注册
        String tokenStr = JSONObject.toJSONString(model, JSONWriter.Feature.IgnoreEmpty);
        String token = DigestUtil.md5Hex(tokenStr);
        CardSellRechargeRequest cardSellRechargeRequest = buildCardSellRechargeRequest(model, token, cardSellInfoResponse);
        String cardSellRechargeRequestBody = request(cardSellRechargeRequest, JynettyApiUriConstant.CARD_SELL_REGISTER);
        ApiResponse<CardSellRechargeResponse> cardSellRechargeApiResponse = JSON.parseObject(cardSellRechargeRequestBody, new TypeReference<ApiResponse<CardSellRechargeResponse>>() {
        });
        if (!cardSellRechargeApiResponse.getSuccess()) {
            return ApiResponse.fail(cardSellRechargeApiResponse.getError());
        }
        CardSellRechargeResponse cardSellRechargeResponse = cardSellRechargeApiResponse.getData();
        if (cardSellRechargeResponse.getCardSellResult() == null || cardSellRechargeResponse.getCardSellResult().isEmpty()) {
            return ApiResponse.fail(new ApiErrorInfo(CARD_REGISTER_ERROR));
        }
        Optional<CardSellResultItemResponse> cardSellResult = cardSellRechargeResponse.getCardSellResult()
                .stream().filter(v -> v.getFacadeCD().equals(cardSellInfoResponse.getFacadeCD())).findFirst();
        if (!cardSellResult.isPresent()) {
            return ApiResponse.fail(new ApiErrorInfo(CARD_REGISTER_ERROR));
        }
        CardRegisterResponseCO result = buildSellInfoResponse(cardSellInfoResponse, CardRegisterResponseCO.class);
        result.setMarking(cardSellResult.get().getGetMarking());
        result.setBalance(result.getCardType().equals("times") ? Convert.toBigDecimal(cardSellResult.get().getBalanceTimes()) : cardSellResult.get().getBalance());
        result.setPlatformOrderCode(model.getPlatformOrderCode());
        result.setCloudOrderCode(model.getPlatformOrderCode());
        result.setClocalOrderCode(cardSellResult.get().getAddID());
        if (!cardSellRechargeResponse.getWalletResultList().isEmpty()) {
            result.setGiftError(StrUtil.join("；", cardSellRechargeResponse.getWalletResultList()));
        }
        result.setGiftDesc(null);
        if (cardSellResult.get().getCardSellGetWallet() != null && cardSellResult.get().getCardSellGetWallet().getCardGetWalletList() != null && !cardSellResult.get().getCardSellGetWallet().getCardGetWalletList().isEmpty()) {
            result.setGiftDesc("");
            for (CardGetWalletListNodeResponse cardGetWalletListNodeResponse : cardSellResult.get().getCardSellGetWallet().getCardGetWalletList()) {
                result.setGiftDesc(result.getGiftDesc() + cardGetWalletListNodeResponse.getGiftTypeDesc() + "*" + cardGetWalletListNodeResponse.getGiftCount() + "；");
            }
        }
        return ApiResponse.success(result);
    }

    /**
     * 组装开卡请求实体
     *
     * @param model                入参
     * @param token                令牌
     * @param cardSellInfoResponse 预制卡信息
     * @return CardSellRechargeRequest
     */
    private @NotNull CardSellRechargeRequest buildCardSellRechargeRequest(CardRegisterRequestCO model, String token, CardSellInfoResponse cardSellInfoResponse) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        CardSellRechargeRequest cardSellRechargeRequest = new CardSellRechargeRequest();
        cardSellRechargeRequest.setTokenNum(token);
        cardSellRechargeRequest.setRandomPwdFlag(false);
        cardSellRechargeRequest.setSellID(model.getCloudOrderCode());
        cardSellRechargeRequest.setInvoiceReceive("N");
        cardSellRechargeRequest.setInvoiceReceiveTime("");
        cardSellRechargeRequest.setOnlineCardSell("Y");
        cardSellRechargeRequest.setOutTradeID(model.getPlatformOrderCode());
        cardSellRechargeRequest.setChannelCD(finixxSettings.getChannelCd());
        cardSellRechargeRequest.setUserID(cardSellRechargeRequest.getChannelCD());
        cardSellRechargeRequest.setBeginFacadeCD(cardSellInfoResponse.getFacadeCD());
        cardSellRechargeRequest.setEndFacadeCD(cardSellInfoResponse.getFacadeCD());
        cardSellRechargeRequest.setNoCardBatchFlag(false);
        cardSellRechargeRequest.setNoCardBatchType(0);
        cardSellRechargeRequest.setSerialCD("");
        cardSellRechargeRequest.setICBCFlag("N");
        cardSellRechargeRequest.setCCBFlag("N");
        cardSellRechargeRequest.setCCBReplace("01");
        cardSellRechargeRequest.setGroupFlag("N");
        cardSellRechargeRequest.setGroupCD("");
        cardSellRechargeRequest.setPaymentTypeFee(model.getPaymentType().getCode());
        cardSellRechargeRequest.setPaymentNameFee(model.getPaymentType().getName());
        cardSellRechargeRequest.setPaymentTypeAdd(model.getPaymentType().getCode());
        cardSellRechargeRequest.setPaymentNameAdd(model.getPaymentType().getName());
        cardSellRechargeRequest.setPaymentNO(model.getCloudOrderCode());
        cardSellRechargeRequest.setAddMoney(model.getRechargeAmount());
        cardSellRechargeRequest.setFee(model.getServiceFee());
        cardSellRechargeRequest.setMembershipFee(model.getMembershipFee());
        cardSellRechargeRequest.setParValue(cardSellInfoResponse.getParValue());
        cardSellRechargeRequest.setCompanyCD("");
        cardSellRechargeRequest.setSalesCD("");
        cardSellRechargeRequest.setPaySalesCD("");
        cardSellRechargeRequest.setBillNO("");
        cardSellRechargeRequest.setWorkstation(cardSellRechargeRequest.getChannelCD());
        cardSellRechargeRequest.setSaleSpeed(new BigDecimal("0"));
        cardSellRechargeRequest.setModule("");
        cardSellRechargeRequest.setValid(cardSellInfoResponse.getValid());
        cardSellRechargeRequest.setMemberName(model.getMemberName());
        cardSellRechargeRequest.setDocumentType(model.getIdCardType());
        cardSellRechargeRequest.setDocumentNO(model.getIdCardNo());
        cardSellRechargeRequest.setUserPassword(model.getCardPassword());
        cardSellRechargeRequest.setMobile(model.getMobilePhone());
        cardSellRechargeRequest.setBirthday(model.getBirthday());
        cardSellRechargeRequest.setEmail("");
        cardSellRechargeRequest.setAddress("");
        cardSellRechargeRequest.setPostCode("");
        cardSellRechargeRequest.setSellExplanation("");
        cardSellRechargeRequest.setPhone("");
        cardSellRechargeRequest.setSex(model.getSex());
        cardSellRechargeRequest.setNation("");
        cardSellRechargeRequest.setNativePlace("");
        cardSellRechargeRequest.setPhotoFlag(false);
        cardSellRechargeRequest.setPhoto("");
        cardSellRechargeRequest.setInvoiceNumber("");
        cardSellRechargeRequest.setWriteShiftFlag(false);
        cardSellRechargeRequest.setAddMoneyID(model.getCloudOrderCode());
        cardSellRechargeRequest.setLocationCd(model.getCinemaLinkId());
        return cardSellRechargeRequest;
    }

    /**
     * 获取会员卡等级
     * {"success":true,"error":null,"data":{"code":"2021","version":"1.0.0.1","serialNumber":"f1011d48bd1843de9b90edfa919f8709","result":0,"message":null,"cardGradeList":[{"gradeID":"1","gradeDesc":"金卡2人版","upgradePolicyCD":"4","relationUsePolicyID":"1","editPolicyFlag":"false"},{"gradeID":"2","gradeDesc":"金卡3人版","upgradePolicyCD":"4","relationUsePolicyID":"2","editPolicyFlag":"false"},{"gradeID":"3","gradeDesc":"金卡4人版","upgradePolicyCD":"4","relationUsePolicyID":"3","editPolicyFlag":"false"},{"gradeID":"4","gradeDesc":"钻石卡","upgradePolicyCD":"4","relationUsePolicyID":"4","editPolicyFlag":"false"},{"gradeID":"5","gradeDesc":"普通会员卡","upgradePolicyCD":"4","relationUsePolicyID":"5","editPolicyFlag":"false"},{"gradeID":"6","gradeDesc":"惠师卡","upgradePolicyCD":"4","relationUsePolicyID":"6","editPolicyFlag":"false"},{"gradeID":"7","gradeDesc":"学生卡","upgradePolicyCD":"4","relationUsePolicyID":"7","editPolicyFlag":"false"},{"gradeID":"8","gradeDesc":"微信在线5折","upgradePolicyCD":"4","relationUsePolicyID":"8","editPolicyFlag":"false"}]}}
     *
     * @param model 入参
     * @return ApiResponse<List < CardGradeResponseCO>>
     */
    @PostMapping("memberCardGrade")
    public ApiResponse<List<CardGradeResponseCO>> memberCardGrade(@RequestBody CardGradeRequestCO model) {
        BaseRequest baseRequest = new BaseRequest();
        baseRequest.setLocationCd(model.getCinemaLinkId());
        String cardSellRechargeRequestBody = request(baseRequest, JynettyApiUriConstant.CARD_GRADE);
        ApiResponse<CardPrefabricateGradeResponse> apiResponse = JSON.parseObject(cardSellRechargeRequestBody, new TypeReference<ApiResponse<CardPrefabricateGradeResponse>>() {
        });
        if (!apiResponse.getSuccess()) {
            return ApiResponse.fail(apiResponse.getError());
        }
        CardPrefabricateGradeResponse cardPrefabricateGradeResponse = apiResponse.getData();
        List<CardGradeResponseCO> result = new ArrayList<>();
        for (CardGradeListItemResponse cardGradeListItemResponse : cardPrefabricateGradeResponse.getCardGradeList()) {
            CardGradeResponseCO item = new CardGradeResponseCO();
            item.setGradeId(cardGradeListItemResponse.getGradeID());
            item.setGradeName(cardGradeListItemResponse.getGradeDesc());
            result.add(item);
        }
        return ApiResponse.success(result);
    }


    /**
     * todo 卡消费
     * {"success":true,"error":null,"data":{"code":"2005","version":"1.0.0.1","serialNumber":"33cee46a07184931893ccff6b912f6cb","result":0,"message":null,"memberCard":{"code":null,"version":null,"serialNumber":null,"result":null,"message":null,"facadeCD":"30000303","oldMemberID":null,"memberID":"30000303","password":"E10ADC3949BA59ABBE56E057F20F883E","avaiFlag":true,"usePolicyID":"8","usePolicyDesc":"8","balance":80.0,"type":"C","state":"N","gradeID":"8","gradeDesc":"微信在线5折","cumulationMarking":0.0,"tradeMarking":0.0,"upgradeMarking":0.0,"addmoneyTM":2.0,"consumeUpgradeTM":1.0,"firstDate":"2025-03-22","lastDate":"2025-03-22","invalidationDate":"2045-03-04T16:00:00.000+00:00","consumePolicyID":"8","relationPass":null,"relationFlag":"N","relationDate":"","locationCD":"8566","locationDesc":"云南普洱墨江电影院","noPassFlag":false,"passwordFlag":"N","birthGiftLastDate":"","balanceTimes":-1.0,"companyCD":null,"salesCD":null,"groupFlag":false,"pointDiscount":1.0,"upgradePolicyCD":"4","remark":" 普通卡, 凭密码消费，可充值型","consumePolicyDesc":"微信在线5折","icbcflag":false,"ccbflag":false,"ccbreplace":"N"},"memberCardResult":[{"result":0,"bookingId":"RO20250322104039833","walletItemSeqNo":null}]}}
     *
     * @return
     */
    @PostMapping("memberCardConsume")
    public ApiResponse<CardConsumeResponse> memberCardConsume(@RequestBody CardConsumeRequestCO model) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        CONCardConsumeRequest conCardConsumeRequest = new CONCardConsumeRequest();
        conCardConsumeRequest.setCardLocationCd(model.getCinemaLinkId());
        conCardConsumeRequest.setLocationCd(model.getCinemaLinkId());
        conCardConsumeRequest.setUserId(finixxSettings.getChannelCd());
        conCardConsumeRequest.setCardFacadeCd(model.getCardNo());
        String tokenStr = JSONObject.toJSONString(model, JSONWriter.Feature.IgnoreEmpty);
        String token = DigestUtil.md5Hex(tokenStr);
        conCardConsumeRequest.setTokenNum(token);
        conCardConsumeRequest.setSerialNumber(IdUtil.fastSimpleUUID());
        //卡密码md5
        conCardConsumeRequest.setCardPassEn(model.getCardPassword());
        //todo 这俩是什么玩意。写卡与手指（指纹）？验证用的吗
        conCardConsumeRequest.setWriteCardFlg(false);
        conCardConsumeRequest.setFingerFlg(false);
        conCardConsumeRequest.setChannelCd(finixxSettings.getChannelCd());
        //todo 一次消费应该是一个影片吧？为什么是个list？
        CONFilmsInfoRequest conFilmsInfoRequest = new CONFilmsInfoRequest();
        conFilmsInfoRequest.setBookingId(model.getBookingId());
        //排期里的refSeqNo
        conFilmsInfoRequest.setSessionRefSeqNo(model.getScheduleCode());
        //连场标识
        conFilmsInfoRequest.setThroughFlg(false);
        conFilmsInfoRequest.setSectionId(model.getSectionCode());
        //todo 也许是这单的总价。也许是会员卡扣的钱
        conFilmsInfoRequest.setTotalAmount(model.getTotalAmount());
        //todo 这两个字段结合来看，好像一个是扣的钱，一个是次数卡的次数？这样的话上面的就是总价了
        conFilmsInfoRequest.setCalculateMarkingMoney(model.getCalculateMarkingMoney());
        conFilmsInfoRequest.setCalculatePerTicketTimes(model.getCalculatePerTicketTimes());
        //todo 受到折扣的座位数量？哪来的折扣，我如何知道该扣多少钱
        conFilmsInfoRequest.setTotalDisSeats(model.getTotalDisSeats());
        //todo 总座位数
        conFilmsInfoRequest.setTotalSeats(model.getTotalSeats());
        //积分
        conFilmsInfoRequest.setTotalConsumeMarking(model.getTotalConsumeMarking());
        conFilmsInfoRequest.setRemarks(model.getRemarks());
        conCardConsumeRequest.setFilmsInfo(CollUtil.newArrayList(conFilmsInfoRequest));

        String requestBody = request(conCardConsumeRequest, JynettyApiUriConstant.CARD_CONSUME);
        ApiResponse<CardConsumeResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<CardConsumeResponse>>() {
        });

        return apiResponse;
    }

    /**
     * 卡消费回滚
     * {"success":true,"error":null,"data":{"code":"2006","version":"1.0.0.1","serialNumber":"ddce021bb4484afe930e9d182ea9988d","result":0,"message":null}}
     *
     * @param model
     * @return
     */
    @PostMapping("memberCardConsumeRollback")
    public ApiResponse<BaseResponse> memberCardConsumeRollback(@RequestBody CardConsumeRollbackRequestCO model) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        ConsumeRollbackRequest conCardConsumeRequest = new ConsumeRollbackRequest();
        conCardConsumeRequest.setCardLocationCd(model.getCinemaLinkId());
        conCardConsumeRequest.setLocationCd(model.getCinemaLinkId());
        conCardConsumeRequest.setCardFacadeCd(model.getCardNo());
        conCardConsumeRequest.setBookingIds(CollUtil.newArrayList(model.getBookingId()));
        conCardConsumeRequest.setUserId(finixxSettings.getChannelCd());
        String tokenStr = JSONObject.toJSONString(model, JSONWriter.Feature.IgnoreEmpty);
        String token = DigestUtil.md5Hex(tokenStr);
        conCardConsumeRequest.setTokenNum(token);
        conCardConsumeRequest.setSerialNumber(IdUtil.fastSimpleUUID());

        String requestBody = request(conCardConsumeRequest, JynettyApiUriConstant.CARD_CONSUME_ROLLBACK);
        ApiResponse<BaseResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<BaseResponse>>() {
        });
        return apiResponse;
    }

    /**
     * 获取排期价格政策
     * <p>
     * {"success":true,"error":null,"data":{"code":"1014","version":"1.0.0.1","serialNumber":"66de6d21570e43429df5f485c27b59d2","result":0,"message":null,"pricePolicys":[],"calculatePerTicketTimes":"0","serviceFee":0.0}}
     *
     * @param model
     * @return
     */
    @PostMapping("getSessionPricePolicy")
    public ApiResponse<SessionPricePolicyResponse> getSessionPricePolicy(@RequestBody SessionPricePolicyCO model) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        SessionPricePolicyRequest sessionPricePolicyRequest = new SessionPricePolicyRequest();
        sessionPricePolicyRequest.setChannelCd(finixxSettings.getChannelCd());
        sessionPricePolicyRequest.setLocationCd(model.getCinemaLinkId());
        sessionPricePolicyRequest.setShowRefSeqNo(model.getScheduleCode());
        sessionPricePolicyRequest.setSectionId(model.getSectionCode());
        //没见过的东西。去掉后报错channelCd不能为空，应该就是ChannelCd
        sessionPricePolicyRequest.setSystemCd(finixxSettings.getChannelCd());
        //连场标识
        sessionPricePolicyRequest.setThroughId(null);
        sessionPricePolicyRequest.setThroughFlg(false);
        sessionPricePolicyRequest.setThroughSeqNo(null);
        //卡政策id
        sessionPricePolicyRequest.setCardUsePolicyId(model.getCardUsePolicyId());
        //卡等级id
        sessionPricePolicyRequest.setCardGradeId(model.getCardGradeId());
        //卡创建日期
        sessionPricePolicyRequest.setCardCreateDate(null);
        //todo 三方什么？
        sessionPricePolicyRequest.setThirdId(null);
        sessionPricePolicyRequest.setThirdFlg(false);
        //todo 最低价标记？这玩意怎么是个字符串？修改类型，修改值，对返回值都没有影响。应该是还没触发？
        sessionPricePolicyRequest.setLeastPriceFlg(false);
        //todo 猜测是分区定价
        sessionPricePolicyRequest.setPricePartitionList(null);

        String requestBody = request(sessionPricePolicyRequest, JynettyApiUriConstant.SESSION_PRICE_POLICY);
        ApiResponse<SessionPricePolicyResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<SessionPricePolicyResponse>>() {
        });
        return apiResponse;
    }

    /**
     * 获取会员卡价格政策
     *
     * @param model
     * @return
     * @throws Exception
     */
    @PostMapping("getCardPricePolicy")
    public ApiResponse<SessionPricePolicyResponse> getCardPricePolicy(@RequestBody @Valid CardPricePolicyCO model) {
        FinixxSettingsDTO finixxSettings = getFinixxSettings();
        CardPricePolicyRequest cardPricePolicyRequest = new CardPricePolicyRequest();
        cardPricePolicyRequest.setLocationCd(model.getCinemaLinkId());
        cardPricePolicyRequest.setThroughSeqNo(null);
        cardPricePolicyRequest.setShowRefSeqNo(model.getScheduleCode());
        cardPricePolicyRequest.setSectionId(model.getSectionCode());
        cardPricePolicyRequest.setSystemCd(finixxSettings.getChannelCd());
        cardPricePolicyRequest.setThroughId(null);
        cardPricePolicyRequest.setThroughFlg(false);
        cardPricePolicyRequest.setCardLocationCd(model.getCinemaLinkId());
        cardPricePolicyRequest.setCardFacadeCd(model.getCardNo());
        cardPricePolicyRequest.setThirdFlg(null);
        cardPricePolicyRequest.setLeastPriceFlg(false);
        cardPricePolicyRequest.setLocationCd(model.getCinemaLinkId());

        String requestBody = request(cardPricePolicyRequest, JynettyApiUriConstant.CARD_PRICE_POLICY);
        ApiResponse<SessionPricePolicyResponse> apiResponse = JSON.parseObject(requestBody, new TypeReference<ApiResponse<SessionPricePolicyResponse>>() {
        });
        return apiResponse;
    }
}
